{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 1:* Download SQuAD 2.0 dataset and Tranformers library"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:24.415965Z",
     "iopub.status.busy": "2023-11-05T03:47:24.415267Z",
     "iopub.status.idle": "2023-11-05T03:47:37.778021Z",
     "shell.execute_reply": "2023-11-05T03:47:37.776710Z",
     "shell.execute_reply.started": "2023-11-05T03:47:24.415932Z"
    }
   },
   "outputs": [],
   "source": [
    "%%capture\n",
    "!pip install transformers"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:37.780873Z",
     "iopub.status.busy": "2023-11-05T03:47:37.780573Z",
     "iopub.status.idle": "2023-11-05T03:47:52.266849Z",
     "shell.execute_reply": "2023-11-05T03:47:52.265796Z",
     "shell.execute_reply.started": "2023-11-05T03:47:37.780845Z"
    }
   },
   "outputs": [],
   "source": [
    "%%capture\n",
    "import json\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "from pathlib import Path\n",
    "import torch\n",
    "from torch.utils.data import DataLoader, TensorDataset\n",
    "from transformers import BertTokenizer, BertForQuestionAnswering\n",
    "import time"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:52.268232Z",
     "iopub.status.busy": "2023-11-05T03:47:52.267940Z",
     "iopub.status.idle": "2023-11-05T03:47:52.336864Z",
     "shell.execute_reply": "2023-11-05T03:47:52.335775Z",
     "shell.execute_reply.started": "2023-11-05T03:47:52.268206Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GPU is available\n"
     ]
    }
   ],
   "source": [
    "is_cuda = torch.cuda.is_available()\n",
    "\n",
    "# If we have a GPU available, we'll set our device to GPU.\n",
    "if is_cuda:\n",
    "    device = torch.device(\"cuda\")\n",
    "    print(\"GPU is available\")\n",
    "else:\n",
    "    device = torch.device(\"cpu\")\n",
    "    print(\"GPU not available, CPU used\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The *Stanford Question Answering Dataset* (SQuAD) consists of questions (100,000) on a set of Wikipedia articles where the answer to every question is a segment of text, or span, from the corresponding reading passage. In second version of SQuAD unanswerable questions were added (50,000) to look similar to answerable ones.\n",
    "\n",
    "The purpose of systems using the SQuAD2.0 dataset, must be not only answer questions when possible, but also determine when no answer is supported by the paragraph and abstain from answering."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:52.340200Z",
     "iopub.status.busy": "2023-11-05T03:47:52.339397Z",
     "iopub.status.idle": "2023-11-05T03:47:55.830068Z",
     "shell.execute_reply": "2023-11-05T03:47:55.828671Z",
     "shell.execute_reply.started": "2023-11-05T03:47:52.340170Z"
    }
   },
   "outputs": [],
   "source": [
    "%%capture\n",
    "!mkdir squad\n",
    "!wget https://rajpurkar.github.io/SQuAD-explorer/dataset/train-v2.0.json -O squad/train-v2.0.json\n",
    "!wget https://rajpurkar.github.io/SQuAD-explorer/dataset/dev-v2.0.json -O squad/dev-v2.0.json"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 2:* Retrieve and Store the data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here I take and store the texts, queries and answers from the train and validation .json files. If we look carefully we will see that in these files there are a number of queries and answers for each passage. I save these informations into lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:55.832136Z",
     "iopub.status.busy": "2023-11-05T03:47:55.831817Z",
     "iopub.status.idle": "2023-11-05T03:47:56.843311Z",
     "shell.execute_reply": "2023-11-05T03:47:56.842429Z",
     "shell.execute_reply.started": "2023-11-05T03:47:55.832105Z"
    }
   },
   "outputs": [],
   "source": [
    "# Define the path to the SQuAD 2.0 training data\n",
    "path = \"squad/train-v2.0.json\"\n",
    "\n",
    "# Load and preprocess the SQuAD 2.0 data\n",
    "def load_squad_data(path):\n",
    "    with open(path, 'rb') as f:\n",
    "        squad_dict = json.load(f)\n",
    "\n",
    "    texts = []\n",
    "    questions = []\n",
    "    answers = []\n",
    "\n",
    "    for group in squad_dict['data']:\n",
    "        for passage in group['paragraphs']:\n",
    "            context = passage['context']\n",
    "            for qa in passage['qas']:\n",
    "                question = qa['question']\n",
    "                for answer in qa['answers']:\n",
    "                    texts.append(context)\n",
    "                    questions.append(question)\n",
    "                    answers.append(answer)\n",
    "\n",
    "    return texts, questions, answers\n",
    "\n",
    "# Preprocess the data to find answer start and end positions\n",
    "train_texts, train_queries, train_answers = load_squad_data(path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:56.845254Z",
     "iopub.status.busy": "2023-11-05T03:47:56.844633Z",
     "iopub.status.idle": "2023-11-05T03:47:57.180616Z",
     "shell.execute_reply": "2023-11-05T03:47:57.179794Z",
     "shell.execute_reply.started": "2023-11-05T03:47:56.845220Z"
    }
   },
   "outputs": [],
   "source": [
    "# Give the path for SQuAD 2.0 validation data\n",
    "path = Path('squad/dev-v2.0.json')\n",
    "\n",
    "# Load and preprocess the SQuAD 2.0 data\n",
    "def load_squad_data(path):\n",
    "    with open(path, 'rb') as f:\n",
    "        squad_dict = json.load(f)\n",
    "\n",
    "    texts = []\n",
    "    questions = []\n",
    "    answers = []\n",
    "\n",
    "    for group in squad_dict['data']:\n",
    "        for passage in group['paragraphs']:\n",
    "            context = passage['context']\n",
    "            for qa in passage['qas']:\n",
    "                question = qa['question']\n",
    "                for answer in qa['answers']:\n",
    "                    texts.append(context)\n",
    "                    questions.append(question)\n",
    "                    answers.append(answer)\n",
    "\n",
    "    return texts, questions, answers\n",
    "\n",
    "# Preprocess the data to find answer start and end positions\n",
    "val_texts, val_queries, val_answers = load_squad_data(path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 3:* Check the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:57.182019Z",
     "iopub.status.busy": "2023-11-05T03:47:57.181727Z",
     "iopub.status.idle": "2023-11-05T03:47:57.187655Z",
     "shell.execute_reply": "2023-11-05T03:47:57.186334Z",
     "shell.execute_reply.started": "2023-11-05T03:47:57.181994Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "86821\n",
      "86821\n",
      "86821\n"
     ]
    }
   ],
   "source": [
    "print(len(train_texts))\n",
    "print(len(train_queries))\n",
    "print(len(train_answers))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:57.189131Z",
     "iopub.status.busy": "2023-11-05T03:47:57.188839Z",
     "iopub.status.idle": "2023-11-05T03:47:57.198830Z",
     "shell.execute_reply": "2023-11-05T03:47:57.197939Z",
     "shell.execute_reply.started": "2023-11-05T03:47:57.189107Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Passage:  Beyoncé Giselle Knowles-Carter (/biːˈjɒnseɪ/ bee-YON-say) (born September 4, 1981) is an American singer, songwriter, record producer and actress. Born and raised in Houston, Texas, she performed in various singing and dancing competitions as a child, and rose to fame in the late 1990s as lead singer of R&B girl-group Destiny's Child. Managed by her father, Mathew Knowles, the group became one of the world's best-selling girl groups of all time. Their hiatus saw the release of Beyoncé's debut album, Dangerously in Love (2003), which established her as a solo artist worldwide, earned five Grammy Awards and featured the Billboard Hot 100 number-one singles \"Crazy in Love\" and \"Baby Boy\".\n",
      "Query:  When did Beyonce start becoming popular?\n",
      "Answer:  {'text': 'in the late 1990s', 'answer_start': 269}\n"
     ]
    }
   ],
   "source": [
    "print(\"Passage: \",train_texts[0])\n",
    "print(\"Query: \",train_queries[0])\n",
    "print(\"Answer: \",train_answers[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:57.200225Z",
     "iopub.status.busy": "2023-11-05T03:47:57.199885Z",
     "iopub.status.idle": "2023-11-05T03:47:57.208671Z",
     "shell.execute_reply": "2023-11-05T03:47:57.207694Z",
     "shell.execute_reply.started": "2023-11-05T03:47:57.200192Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20302\n",
      "20302\n",
      "20302\n"
     ]
    }
   ],
   "source": [
    "print(len(val_texts))\n",
    "print(len(val_queries))\n",
    "print(len(val_answers))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:57.212461Z",
     "iopub.status.busy": "2023-11-05T03:47:57.212182Z",
     "iopub.status.idle": "2023-11-05T03:47:57.219178Z",
     "shell.execute_reply": "2023-11-05T03:47:57.218136Z",
     "shell.execute_reply.started": "2023-11-05T03:47:57.212438Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Passage:  The Normans (Norman: Nourmands; French: Normands; Latin: Normanni) were the people who in the 10th and 11th centuries gave their name to Normandy, a region in France. They were descended from Norse (\"Norman\" comes from \"Norseman\") raiders and pirates from Denmark, Iceland and Norway who, under their leader Rollo, agreed to swear fealty to King Charles III of West Francia. Through generations of assimilation and mixing with the native Frankish and Roman-Gaulish populations, their descendants would gradually merge with the Carolingian-based cultures of West Francia. The distinct cultural and ethnic identity of the Normans emerged initially in the first half of the 10th century, and it continued to evolve over the succeeding centuries.\n",
      "Query:  In what country is Normandy located?\n",
      "Answer:  {'text': 'France', 'answer_start': 159}\n"
     ]
    }
   ],
   "source": [
    "print(\"Passage: \",val_texts[0])\n",
    "print(\"Query: \",val_queries[0])\n",
    "print(\"Answer: \",val_answers[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 4:* Find the start and end position character"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:57.220818Z",
     "iopub.status.busy": "2023-11-05T03:47:57.220439Z",
     "iopub.status.idle": "2023-11-05T03:47:57.318826Z",
     "shell.execute_reply": "2023-11-05T03:47:57.317906Z",
     "shell.execute_reply.started": "2023-11-05T03:47:57.220787Z"
    }
   },
   "outputs": [],
   "source": [
    "for answer, text in zip(train_answers, train_texts):\n",
    "    real_answer = answer['text']\n",
    "    start_idx = answer['answer_start']\n",
    "    # Get the real end index\n",
    "    end_idx = start_idx + len(real_answer)\n",
    "\n",
    "    # Deal with the problem of 1 or 2 more characters\n",
    "    if text[start_idx:end_idx] == real_answer:\n",
    "        answer['answer_end'] = end_idx\n",
    "    # When the real answer is more by one character\n",
    "    elif text[start_idx-1:end_idx-1] == real_answer:\n",
    "        answer['answer_start'] = start_idx - 1\n",
    "        answer['answer_end'] = end_idx - 1\n",
    "    # When the real answer is more by two characters\n",
    "    elif text[start_idx-2:end_idx-2] == real_answer:\n",
    "        answer['answer_start'] = start_idx - 2\n",
    "        answer['answer_end'] = end_idx - 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:57.320285Z",
     "iopub.status.busy": "2023-11-05T03:47:57.319937Z",
     "iopub.status.idle": "2023-11-05T03:47:57.349498Z",
     "shell.execute_reply": "2023-11-05T03:47:57.348505Z",
     "shell.execute_reply.started": "2023-11-05T03:47:57.320259Z"
    }
   },
   "outputs": [],
   "source": [
    "for answer, text in zip(val_answers, val_texts):\n",
    "    real_answer = answer['text']\n",
    "    start_idx = answer['answer_start']\n",
    "    # Get the real end index\n",
    "    end_idx = start_idx + len(real_answer)\n",
    "\n",
    "    # Deal with the problem of 1 or 2 more characters\n",
    "    if text[start_idx:end_idx] == real_answer:\n",
    "        answer['answer_end'] = end_idx\n",
    "    # When the real answer is more by one character\n",
    "    elif text[start_idx-1:end_idx-1] == real_answer:\n",
    "        answer['answer_start'] = start_idx - 1\n",
    "        answer['answer_end'] = end_idx - 1\n",
    "    # When the real answer is more by two characters\n",
    "    elif text[start_idx-2:end_idx-2] == real_answer:\n",
    "        answer['answer_start'] = start_idx - 2\n",
    "        answer['answer_end'] = end_idx - 2\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 5:* Tokenize passages and queries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:57.351010Z",
     "iopub.status.busy": "2023-11-05T03:47:57.350725Z",
     "iopub.status.idle": "2023-11-05T03:47:58.169310Z",
     "shell.execute_reply": "2023-11-05T03:47:58.168315Z",
     "shell.execute_reply.started": "2023-11-05T03:47:57.350985Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e748149fb6d842009fcb9ebdb4c6f979",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)okenizer_config.json:   0%|          | 0.00/28.0 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f258afbe230e4bae92b7c7cbc4be64c9",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)lve/main/config.json:   0%|          | 0.00/570 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "99a490c0b760412393259062807846f5",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)solve/main/vocab.txt:   0%|          | 0.00/232k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "ad6c519829ca4b05a33a165a0f72fce1",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)/main/tokenizer.json:   0%|          | 0.00/466k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from transformers import AutoTokenizer\n",
    "tokenizer = AutoTokenizer.from_pretrained(\"bert-base-uncased\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:47:58.170781Z",
     "iopub.status.busy": "2023-11-05T03:47:58.170489Z",
     "iopub.status.idle": "2023-11-05T03:48:35.696574Z",
     "shell.execute_reply": "2023-11-05T03:48:35.695590Z",
     "shell.execute_reply.started": "2023-11-05T03:47:58.170757Z"
    }
   },
   "outputs": [],
   "source": [
    "train_encodings = tokenizer(train_texts, train_queries, truncation=True, padding=True)\n",
    "val_encodings = tokenizer(val_texts, val_queries, truncation=True, padding=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 6:* Convert the start-end positions to tokens start-end positions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:48:35.698562Z",
     "iopub.status.busy": "2023-11-05T03:48:35.697979Z",
     "iopub.status.idle": "2023-11-05T03:48:36.163632Z",
     "shell.execute_reply": "2023-11-05T03:48:36.162674Z",
     "shell.execute_reply.started": "2023-11-05T03:48:35.698504Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10\n",
      "16\n"
     ]
    }
   ],
   "source": [
    "def add_token_positions(encodings, answers):\n",
    "    start_positions = []\n",
    "    end_positions = []\n",
    "    \n",
    "    count = 0\n",
    "    \n",
    "    for i in range(len(answers)):\n",
    "        start_positions.append(encodings.char_to_token(i, answers[i]['answer_start']))\n",
    "        end_positions.append(encodings.char_to_token(i, answers[i]['answer_end']))\n",
    "        \n",
    "        # if start position is None, the answer passage has been truncated\n",
    "        if start_positions[-1] is None:\n",
    "            start_positions[-1] = tokenizer.model_max_length\n",
    "            \n",
    "        # if end position is None, the 'char_to_token' function points to the space after the correct token, so add - 1\n",
    "        if end_positions[-1] is None:\n",
    "            end_positions[-1] = encodings.char_to_token(i, answers[i]['answer_end'] - 1)\n",
    "            \n",
    "            # if end position is still None the answer passage has been truncated\n",
    "            if end_positions[-1] is None:\n",
    "                count += 1\n",
    "                end_positions[-1] = tokenizer.model_max_length\n",
    "    print(count)\n",
    "    \n",
    "    # Update the data in dictionary\n",
    "    encodings.update({'start_positions': start_positions, 'end_positions': end_positions})\n",
    "\n",
    "add_token_positions(train_encodings, train_answers)\n",
    "add_token_positions(val_encodings, val_answers)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I observed that after tokenize the end position character, sometimes was still None. This happended only for 10 answers in train data (of total 86821) and 16 answers in validation data (of total 20302). So I decided to move the answer 1 position left. If it was still None then I give them the model_max_length as before. I have to refer that I was trying to see if the answers in this case was 1 postition after (so I added +1 to the end position) or 2 positions left or right (+/- 2 positions), but the answers that there are still None was more (ie 526, while with this code there only 10). So I kept this strategy in the end, in order to have as less as possible \"burned\" answers."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 7:* Create a Dataset class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:48:36.165352Z",
     "iopub.status.busy": "2023-11-05T03:48:36.165064Z",
     "iopub.status.idle": "2023-11-05T03:48:36.171402Z",
     "shell.execute_reply": "2023-11-05T03:48:36.170481Z",
     "shell.execute_reply.started": "2023-11-05T03:48:36.165327Z"
    }
   },
   "outputs": [],
   "source": [
    "class SquadDataset(torch.utils.data.Dataset):\n",
    "    def __init__(self, encodings):\n",
    "        self.encodings = encodings\n",
    "\n",
    "    def __getitem__(self, idx):\n",
    "        return {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}\n",
    "\n",
    "    def __len__(self):\n",
    "        return len(self.encodings.input_ids)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:48:36.172919Z",
     "iopub.status.busy": "2023-11-05T03:48:36.172604Z",
     "iopub.status.idle": "2023-11-05T03:48:36.180892Z",
     "shell.execute_reply": "2023-11-05T03:48:36.180061Z",
     "shell.execute_reply.started": "2023-11-05T03:48:36.172873Z"
    }
   },
   "outputs": [],
   "source": [
    "train_dataset = SquadDataset(train_encodings)\n",
    "val_dataset = SquadDataset(val_encodings)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 8:* Use of DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:48:36.182346Z",
     "iopub.status.busy": "2023-11-05T03:48:36.182075Z",
     "iopub.status.idle": "2023-11-05T03:48:36.191353Z",
     "shell.execute_reply": "2023-11-05T03:48:36.190543Z",
     "shell.execute_reply.started": "2023-11-05T03:48:36.182315Z"
    }
   },
   "outputs": [],
   "source": [
    "train_loader = DataLoader(train_dataset, batch_size=8, shuffle=True)\n",
    "val_loader = DataLoader(val_dataset, batch_size=8, shuffle=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 9:* Use GPU"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:48:36.192798Z",
     "iopub.status.busy": "2023-11-05T03:48:36.192463Z",
     "iopub.status.idle": "2023-11-05T03:48:36.200724Z",
     "shell.execute_reply": "2023-11-05T03:48:36.199850Z",
     "shell.execute_reply.started": "2023-11-05T03:48:36.192769Z"
    }
   },
   "outputs": [],
   "source": [
    "device = torch.device('cuda:0' if torch.cuda.is_available()\n",
    "                      else 'cpu')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 10:* Build the Bert model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I select BertForQuestionAnswering from transformers library, as it was the most relative with this task. When we instantiate a model with from_pretrained(), the model configuration and pre-trained weights of the specified model are used to initialize the model. Moreover, I used the PyTorch optimizer of AdamW which implements gradient bias correction as well as weight decay."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:48:36.201927Z",
     "iopub.status.busy": "2023-11-05T03:48:36.201668Z",
     "iopub.status.idle": "2023-11-05T03:48:45.749171Z",
     "shell.execute_reply": "2023-11-05T03:48:45.747971Z",
     "shell.execute_reply.started": "2023-11-05T03:48:36.201905Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "6a6bd80600954e1fbfd5f6e8384cfead",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading model.safetensors:   0%|          | 0.00/440M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "model = BertForQuestionAnswering.from_pretrained('bert-base-uncased').to(device)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:48:45.750904Z",
     "iopub.status.busy": "2023-11-05T03:48:45.750605Z",
     "iopub.status.idle": "2023-11-05T03:48:45.762817Z",
     "shell.execute_reply": "2023-11-05T03:48:45.761708Z",
     "shell.execute_reply.started": "2023-11-05T03:48:45.750876Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/opt/conda/lib/python3.10/site-packages/transformers/optimization.py:411: FutureWarning: This implementation of AdamW is deprecated and will be removed in a future version. Use the PyTorch implementation torch.optim.AdamW instead, or set `no_deprecation_warning=True` to disable this warning\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "from transformers import AdamW\n",
    "optim = AdamW(model.parameters(), lr=5e-5)\n",
    "\n",
    "epochs = 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 11:* Train and Evaluate Model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T03:48:45.766807Z",
     "iopub.status.busy": "2023-11-05T03:48:45.766278Z",
     "iopub.status.idle": "2023-11-05T11:44:12.019915Z",
     "shell.execute_reply": "2023-11-05T11:44:12.018800Z",
     "shell.execute_reply.started": "2023-11-05T03:48:45.766780Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "############Train############\n",
      "Batch 1000 / 10853 \n",
      "Loss: 1.7 \n",
      "\n",
      "Batch 2000 / 10853 \n",
      "Loss: 1.6 \n",
      "\n",
      "Batch 3000 / 10853 \n",
      "Loss: 0.9 \n",
      "\n",
      "Batch 4000 / 10853 \n",
      "Loss: 1.5 \n",
      "\n",
      "Batch 5000 / 10853 \n",
      "Loss: 1.2 \n",
      "\n",
      "Batch 6000 / 10853 \n",
      "Loss: 0.9 \n",
      "\n",
      "Batch 7000 / 10853 \n",
      "Loss: 0.9 \n",
      "\n",
      "Batch 8000 / 10853 \n",
      "Loss: 1.0 \n",
      "\n",
      "Batch 9000 / 10853 \n",
      "Loss: 2.1 \n",
      "\n",
      "Batch 10000 / 10853 \n",
      "Loss: 0.3 \n",
      "\n",
      "############Evaluate############\n",
      "Batch 1000 / 2538 \n",
      "Loss: 2.0 \n",
      "\n",
      "Batch 2000 / 2538 \n",
      "Loss: 0.6 \n",
      "\n",
      "\n",
      "-------Epoch  1 -------\n",
      "Training Loss: 1.3305625837142814 \n",
      "Validation Loss: 1.1514507515562906 \n",
      "Time:  9507.142520189285 \n",
      "----------------------- \n",
      "\n",
      "\n",
      "############Train############\n",
      "Batch 1000 / 10853 \n",
      "Loss: 1.1 \n",
      "\n",
      "Batch 2000 / 10853 \n",
      "Loss: 0.8 \n",
      "\n",
      "Batch 3000 / 10853 \n",
      "Loss: 1.5 \n",
      "\n",
      "Batch 4000 / 10853 \n",
      "Loss: 1.2 \n",
      "\n",
      "Batch 5000 / 10853 \n",
      "Loss: 1.5 \n",
      "\n",
      "Batch 6000 / 10853 \n",
      "Loss: 0.3 \n",
      "\n",
      "Batch 7000 / 10853 \n",
      "Loss: 0.5 \n",
      "\n",
      "Batch 8000 / 10853 \n",
      "Loss: 1.6 \n",
      "\n",
      "Batch 9000 / 10853 \n",
      "Loss: 0.5 \n",
      "\n",
      "Batch 10000 / 10853 \n",
      "Loss: 0.5 \n",
      "\n",
      "############Evaluate############\n",
      "Batch 1000 / 2538 \n",
      "Loss: 0.6 \n",
      "\n",
      "Batch 2000 / 2538 \n",
      "Loss: 0.6 \n",
      "\n",
      "\n",
      "-------Epoch  2 -------\n",
      "Training Loss: 0.8772518780629261 \n",
      "Validation Loss: 1.1670450934915677 \n",
      "Time:  9511.289120197296 \n",
      "----------------------- \n",
      "\n",
      "\n",
      "############Train############\n",
      "Batch 1000 / 10853 \n",
      "Loss: 0.4 \n",
      "\n",
      "Batch 2000 / 10853 \n",
      "Loss: 0.9 \n",
      "\n",
      "Batch 3000 / 10853 \n",
      "Loss: 0.7 \n",
      "\n",
      "Batch 4000 / 10853 \n",
      "Loss: 1.2 \n",
      "\n",
      "Batch 5000 / 10853 \n",
      "Loss: 0.9 \n",
      "\n",
      "Batch 6000 / 10853 \n",
      "Loss: 0.4 \n",
      "\n",
      "Batch 7000 / 10853 \n",
      "Loss: 0.1 \n",
      "\n",
      "Batch 8000 / 10853 \n",
      "Loss: 1.2 \n",
      "\n",
      "Batch 9000 / 10853 \n",
      "Loss: 0.8 \n",
      "\n",
      "Batch 10000 / 10853 \n",
      "Loss: 0.3 \n",
      "\n",
      "############Evaluate############\n",
      "Batch 1000 / 2538 \n",
      "Loss: 1.0 \n",
      "\n",
      "Batch 2000 / 2538 \n",
      "Loss: 0.7 \n",
      "\n",
      "\n",
      "-------Epoch  3 -------\n",
      "Training Loss: 0.6817932915080489 \n",
      "Validation Loss: 1.2011212446030386 \n",
      "Time:  9507.805643320084 \n",
      "----------------------- \n",
      "\n",
      "\n",
      "Total training and evaluation time:  28526.238472938538\n"
     ]
    }
   ],
   "source": [
    "whole_train_eval_time = time.time()\n",
    "\n",
    "train_losses = []\n",
    "val_losses = []\n",
    "\n",
    "print_every = 1000\n",
    "\n",
    "for epoch in range(epochs):\n",
    "    epoch_time = time.time()\n",
    "    \n",
    "    # Set model in train mode\n",
    "    model.train()\n",
    "    loss_of_epoch = 0\n",
    "    \n",
    "    print(\"############Train############\")\n",
    "    \n",
    "    for batch_idx,batch in enumerate(train_loader): \n",
    "        optim.zero_grad()\n",
    "        \n",
    "        input_ids = batch['input_ids'].to(device)\n",
    "        attention_mask = batch['attention_mask'].to(device)\n",
    "        start_positions = batch['start_positions'].to(device)\n",
    "        end_positions = batch['end_positions'].to(device)\n",
    "        \n",
    "        outputs = model(input_ids, attention_mask=attention_mask, start_positions=start_positions, end_positions=end_positions)\n",
    "        loss = outputs[0]\n",
    "        # do a backwards pass \n",
    "        loss.backward()\n",
    "        # update the weights\n",
    "        optim.step()\n",
    "        # Find the total loss\n",
    "        loss_of_epoch += loss.item()\n",
    "        \n",
    "        if (batch_idx+1) % print_every == 0:\n",
    "            print(\"Batch {:} / {:}\".format(batch_idx+1,len(train_loader)),\"\\nLoss:\", round(loss.item(),1),\"\\n\")\n",
    "        \n",
    "    loss_of_epoch /= len(train_loader)\n",
    "    train_losses.append(loss_of_epoch)\n",
    "    \n",
    "    ##########Evaluation##################\n",
    "    \n",
    "    # Set model in evaluation mode\n",
    "    model.eval()\n",
    "    \n",
    "    print(\"############Evaluate############\")\n",
    "    \n",
    "    loss_of_epoch = 0\n",
    "    \n",
    "    for batch_idx,batch in enumerate(val_loader):\n",
    "        \n",
    "        with torch.no_grad():\n",
    "            \n",
    "            input_ids = batch['input_ids'].to(device)\n",
    "            attention_mask = batch['attention_mask'].to(device)\n",
    "            start_positions = batch['start_positions'].to(device)\n",
    "            end_positions = batch['end_positions'].to(device)\n",
    "            \n",
    "            outputs = model(input_ids, attention_mask=attention_mask, start_positions=start_positions, end_positions=end_positions)\n",
    "            loss = outputs[0]\n",
    "            # Find the total loss\n",
    "            loss_of_epoch += loss.item()\n",
    "            \n",
    "        if (batch_idx+1) % print_every == 0:\n",
    "            print(\"Batch {:} / {:}\".format(batch_idx+1,len(val_loader)),\"\\nLoss:\", round(loss.item(),1),\"\\n\")\n",
    "    \n",
    "    loss_of_epoch /= len(val_loader)\n",
    "    val_losses.append(loss_of_epoch)\n",
    "    \n",
    "    # Print each epoch's time and train/val loss \n",
    "    \n",
    "    print(\"\\n-------Epoch \", epoch+1,\n",
    "          \"-------\"\n",
    "          \"\\nTraining Loss:\", train_losses[-1],\n",
    "          \"\\nValidation Loss:\", val_losses[-1],\n",
    "          \"\\nTime: \",(time.time() - epoch_time),\n",
    "          \"\\n-----------------------\",\n",
    "          \"\\n\\n\")\n",
    "\n",
    "print(\"Total training and evaluation time: \", (time.time() - whole_train_eval_time))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 12:* Plot train and validation losses"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:46:24.585950Z",
     "iopub.status.busy": "2023-11-05T11:46:24.585215Z",
     "iopub.status.idle": "2023-11-05T11:46:24.913426Z",
     "shell.execute_reply": "2023-11-05T11:46:24.912588Z",
     "shell.execute_reply.started": "2023-11-05T11:46:24.585913Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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RESkx9jDRUREREREpCMMXERERERERDrCwEVERERERKQjDFxEREREREQ6wsBFRERERESkIwxcREREREREOmJYdhMCAJVKhSdPnsDCwgKCIEhdDhERERERSUQURaSkpMDZ2RkyWel9WAxc5fTkyRO4urpKXQYREREREdUQDx8+RP369Uttw8BVThYWFgDyT6qlpaXE1RARERERkVSSk5Ph6uqqzgilYeAqp4JhhJaWlgxcRERERERUrluNOGkGERERERGRjjBwERERERER6QgDFxERERERkY7wHi4iIiIiolpGFEXk5uYiLy9P6lL0lpGREQwMDKq8HwYuIiIiIqJaJDs7G9HR0UhPT5e6FL0mCALq168Pc3PzKu2HgYuIiIiIqJZQqVSIioqCgYEBnJ2dIZfLyzWTHmkSRRHx8fF49OgRPDw8qtTTxcBFRERERFRLZGdnQ6VSwdXVFaamplKXo9fs7e1x79495OTkVClwcdIMIiIiIqJaRibjr/lVpa2eQX4niIiIiIiIdISBi4iIiIiISEcYuIiIiIiIqNZp2LAhlixZInUZDFxERERERCQdQRBKfS1YsKBS+z1//jz+9a9/abfYSuAshXoqOTMHlsZGUpdBRERERFQl0dHR6q83bdqEefPm4ebNm+plhZ+DJYoi8vLyYGhYdoyxt7fXbqGVxB4uPXQzJgVdPj+MH47fhUolSl0OEREREdVgoigiPTu32l+iWL7fUx0dHdUvKysrCIKgfh8REQELCwvs3bsXbdu2hUKhwIkTJ3Dnzh0MGjQIDg4OMDc3R/v27XHo0CGN/b44pFAQBPzwww8YMmQITE1N4eHhgT/++EObp7pY7OHSQ1v+eoiUzFx8sjscIeFx+HqED1ysTaQui4iIiIhqoIycPDSft7/aP/fGR31gKtdO3Hjvvffw9ddfw93dHfXq1cPDhw/Rv39/fPrpp1AoFPj5558xcOBA3Lx5Ew0aNChxPx9++CG+/PJLfPXVV1i2bBleffVV3L9/HzY2Nlqpszjs4dJD/zfAC58OaQkTIwOcvvsUfReHYselR+X+KwIRERERkT756KOP0KtXLzRu3Bg2Njbw8fHBG2+8gZYtW8LDwwMff/wxGjduXGaP1YQJEzB69Gg0adIEn332GVJTU3Hu3Dmd1s4eLj0kCAJe9XND58Z2mLU5DJceJGLmpss4dCMO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h4uLCxYuXKixnb+/P1xcXLBx48YKfR6nhSciIiIiKr+Hz9JxOCIuf+jhnafIzlOp11koDBHQzB6Bnkr0aKZEPTP9GnpYJ+7hGjlyJOLj4zFv3jzExMTA19cX+/btg4ODAwDgwYMHkMk0U/PNmzdx4sQJHDhwQIqSiYiIiIjqDFcbUwR3bojgzg2RmpWLE7fjEfL30MOE1GzsvhKN3X8PPWzrVg89PR0Q5KVEE2XtGnqotz1c1Y09XEREREREVadSiQh7lIjD4XE4FB6LiJgUjfUNbEzR01OJIC8HdGhUM4ce1vpp4aXAwEVEREREpH2PEzNwODwWh8LjcPqFoYfmCkMENLVDT08H9GhmD1vzmjGLOAOXDjBwERERERHpVlpWLk5EJuBweP69Xwmp/zwXVxCANg3q4f3+nmjrZiNhlXXkHi4iIiIiIqpdzBSG6NPCEX1aOEKlEnHlcZK69+tGdDIu3H8OU7l+RRj9qpaIiIiIiOoEmUyAr6s1fF2tMat3MzxJzMCJyAR4OlpIXVqFMHAREREREVGN52xtghHtXKUuo8Jq3pQfREREREREtQQDFxERERERkY4wcBEREREREekIAxcREREREZGOMHARERERERHpCAMXERERERGRjjBwERERERER6QgDFxERERERkY4wcBEREREREekIAxcREREREZGOMHARERERERHpCAMXERERERGRjjBwERERERER6QgDFxERERERkY4YSl2AvhBFEQCQnJwscSVERERERCSlgkxQkBFKw8BVTikpKQAAV1dXiSshIiIiIqKaICUlBVZWVqW2EcTyxDKCSqXCkydPYGFhAUEQpC4HycnJcHV1xcOHD2FpaSl1ObUOz69u8fzqFs+vbvH86hbPr27x/OoWz69u1aTzK4oiUlJS4OzsDJms9Lu02MNVTjKZDPXr15e6jCIsLS0lv+BqM55f3eL51S2eX93i+dUtnl/d4vnVLZ5f3aop57esnq0CnDSDiIiIiIhIRxi4iIiIiIiIdISBS08pFArMnz8fCoVC6lJqJZ5f3eL51S2eX93i+dUtnl/d4vnVLZ5f3dLX88tJM4iIiIiIiHSEPVxEREREREQ6wsBFRERERESkIwxcREREREREOsLARUREREREpCMMXDXEihUr0LBhQxgbG8PPzw/nzp0rtf2WLVvg6ekJY2NjeHt7Y8+e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p0+fwsnJSSt164vKnt/C8vLycPXqVfW54/X7j6qc3y1btiArKwtjx44t83Pq6vVbGWX9/NXGv4m6bsOGDZg4cSI2bNig8TiDkqSmpuLOnTu8fispLCxMfe54/WrHsWPHEBkZWa4/eNXl61cURUybNg07duzA4cOH0ahRozK30dvfgSWbroPUNm7cKCoUCnHt2rXijRs3xH/961+itbW1GBMTI4qiKI4bN05877331O1PnjwpGhoail9//bUYHh4uzp8/XzQyMhKvXr2qbvP555+L1tbW4u+//y5euXJFHDRokNioUSMxIyOj2o9PahU9v59//rkol8vFrVu3itHR0epXSkqKKIqimJKSIs6ePVs8ffq0GBUVJR46dEhs06aN6OHhIWZmZkpyjFKq6Pn98MMPxf3794t37twRL1y4II4aNUo0NjYWr1+/rm7D6/cfFT2/Bbp27SqOHDmyyHJev5pSUlLES5cuiZcuXRIBiIsWLRIvXbok3r9/XxRFUXzvvffEcePGqdvfvXtXNDU1Ff/zn/+I4eHh4ooVK0QDAwNx37596jZlfc/qkoqe319//VU0NDQUV6xYofHzNzExUd3mnXfeEY8ePSpGRUWJJ0+eFIOCgkQ7OzsxLi6u2o9PahU9v4sXLxZ37twp3r59W7x69ao4ffp0USaTiYcOHVK34fX7j4qe3wJjx44V/fz8it0nr99/TJkyRbSyshKPHj2q8e89PT1d3aa2/A7MwFVDLFu2TGzQoIEol8vFDh06iGfOnFGv69atmxgcHKzRfvPmzWLTpk1FuVwutmjRQty9e7fGepVKJX7wwQeig4ODqFAoxMDAQPHmzZvVcSg1UkXOr5ubmwigyGv+/PmiKIpienq62Lt3b9He3l40MjIS3dzcxNdff71O/s+oQEXO74wZM9RtHRwcxP79+4sXL17U2B+vX00V/fkQEREhAhAPHDhQZF+8fjUVTJP94qvgnAYHB4vdunUrso2vr68ol8tFd3d3cc2aNUX2W9r3rC6p6Pnt1q1bqe1FMX8aficnJ1Eul4suLi7iyJEjxcjIyOo9sBqiouf3iy++EBs3biwaGxuLNjY2Yvfu3cXDhw8X2S+v33yV+fmQmJgompiYiN99912x++T1+4/izi0AjZ+pteV3YEEURVFn3WdERERERER1GO/hIiIiIiIi0hEGLiIiIiIiIh1h4CIiIiIiItIRBi4iIiIiIiIdYeAiIiIiIiLSEQYuIiIiIiIiHWHgIiIiIiIi0hEGLiIiIiIiIh1h4CIiIqphFixYAEEQIAgCJkyYIHU5RERUBQxcRESkFRMmTFCHhMq81q5dK/UhEBERaR0DFxERERERkY4YSl0AERHVPvXq1UOHDh0qtI2Li4uOqiEiIpIOAxcREWldq1atsG/fPqnLICIikhyHFBIREREREekIAxcREREREZGOMHAREVGNVXgWw3v37gEAYmJi8Mknn6Bdu3awt7eHqakpPDw88MYbb+DixYsV/ozHjx/j008/RZcuXeDk5ASFQgGlUom2bdtizpw5CA8Pr1TtYWFheP/99+Hn5wdnZ2coFAqYm5vDw8MDr7zyClatWoX4+PgK7fPMmTOYMGECmjZtClNTU9SrVw/t27fHRx99hKSkpHLv59y5c5g2bRratGkDGxsbGBoawtTUFM7OzujSpQumTp2KzZs3Iy0traKHTURELxKJiIi0IDg4WAQgAhC7deumlX0W7A+AGBUVJe7fv1+0sbHRWF74JZPJxDlz5ogqlapc+//f//4nmpmZlbg/AKKhoaE4c+ZMMScnp1z7jIuLE4cNGyYKglDqfgGIcrlcjIiIKLKP+fPnq9sEBweL2dnZ4owZM0rdl6Ojo3jlypVSa8vMzBTHjx9fZl0Fr379+pXrmImIqGScNIOIiPTCxYsXMXr0aGRnZ0MQBDRv3hz29vZ49OgRIiMjAQAqlQoLFy5ERkYGFi9eXOr+3nnnHSxatEhjWZMmTVC/fn0kJCTg+vXrEEURubm5WLx4Me7evYutW7fC0LDk/3VGRkaiT58+uHv3rsbypk2bwsnJCbm5uXjw4AEePnwIAMjOzkZGRkaZxz5lyhT8+OOPAABbW1s0a9YMBgYGuHbtGp4/fw4gv+evb9++CA8Ph6WlZbH7mThxIjZs2KB+b2hoiGbNmkGpVEIURTx79gy3bt1CZmYmgPzzSUREVSR14iMiotpB1z1cdnZ2IgAxKChIjIyM1Gh36dIlsU2bNhrtd+/eXeJ+N2/erNG2ffv2YlhYmEabe/fuiS+99JJGu48++qjEfaalpYnNmzfX6G2bPn26+OjRoyJtHz16JC5ZskRs3LixeOnSpSLrC/dw2draigDE+vXrizt37hTz8vLU7XJycsTPP/9cozdt7ty5xdb3119/aRzL3LlzxefPnxdpl5ubK548eVJ8++23xeHDh5d4vEREVD4MXEREpBW6DlwAxB49eojZ2dnFtk1KStIIPE2aNCl2aGFWVpbo6OiobtemTRsxNTW12H3m5eWJL7/8srqtkZGR+PDhw2Lb/uc//9EIW5s2bSrz+HJycsSMjIwiywsHLgCiUqkU79+/X+J+3nrrLXVbV1fXYtt89NFH6jZjx44tszZRzA9fRERUNZw0g4iItO7YsWMaE16U9WrYsGGZ+zQyMsL3338PIyOjYtdbWlpi1apV6veRkZE4dOhQkXbbtm1DTEwMgPxJOX788UeYmZkVu0+ZTIbvvvsOFhYWAICcnBysXr26SLukpCR8++236vdvv/02RowYUeYxGRoawtjYuMx2X3/9NRo0aFDi+hkzZqi/fvjwoXrIYmGPHj1Sf92lS5cyPxMADAwMytWOiIhKxsBFRER6oX///mjcuHGpbQICAuDt7a1+v3PnziJtCi/r1q0bfH19S92ng4MDxowZU+o+//zzT6SkpADID4bvvfdeqfusCEtLS4waNarUNu7u7nB2dla/j4iIKNKmcLC7cuWK1uojIqLScdIMIiLSunr16qFDhw7lbu/g4FBmm759+5ZrX/369cPVq1cBAOfPny+y/uzZsxpty+Oll15S92zduHEDKSkp6l4vADh+/Lj66y5dupTreMqrbdu2JfbqFebi4oInT54AABITE4vdT4HVq1ejadOmeOONN2BiYqK1WomIqCgGLiIi0rpWrVph3759Wt1ny5Yty9WuRYsW6q9v376tsS43Nxf3799Xvy/cG1aawu1UKhWioqLQqlUr9bLCz+oqHGy0wdHRsVztTE1N1V+np6cXWT9s2DC8//77ePz4MVQqFWbOnIn58+ejd+/e6N69O/z9/eHt7Q1BELRWOxERcUghERHpCVtb2wq3S05OhiiK6vcv9vyUd592dnYa7wumYi/w7Nkz9df29vbl2md5yeXyCm9T+JgLmJqaYteuXRpDD5OTk7F161ZMmzYNPj4+UCqVmDBhgkaPHRERVQ0DFxER6YXyBg+FQqH+WqVSIScnR/0+KyurUvt8sd2L+yn8vvDn1zStW7dGeHg4PvnkEzRp0qTI+oSEBKxbtw4BAQF46aWXkJCQIEGVRES1CwMXERHphYJJKSrSTqFQaIQlKyurKu8TAKytrUt8n5SUVK59SsXS0hL/93//h9u3b+POnTv48ccfMX78eLi4uGi02717N/r27Yvc3FyJKiUiqh0YuIiISC9ERUVVuJ1SqdRYZ25urjFJRHn3eefOHY33Lw4bLHyf1Yv3jdVk7u7umDRpEtatW4eHDx/i+PHj6Natm3r9hQsXsGHDBgkrJCLSfwxcRESkF86dO1fhdm3atCmyvnXr1hXeZ+GZDevVq1fkuWEdO3ZUf338+PFi76Gq6QRBQNeuXbFv3z54enqqlx84cEDCqoiI9B8DFxER6YUtW7ZApVKV2iY1NRW7d+9Wv+/atWuRNv7+/uqvt23bpnGPV0l++eUXjX2+OJNfr1691F8/ePBAr0OKsbEx+vTpo34fGxsrYTVERPqPgYuIiPTCnTt38NNPP5XaZuHChUhNTQUAGBoaYuzYsUXaTJw4Uf11TEwMli5dWuo+t23bptHD9dprrxVp0759e43njk2fPr3YqdmlVJFet8L3rNnY2OiiHCKiOoOBi4iI9Mbbb7+No0ePFrtuw4YN+Pzzz9Xvg4ODi32GVbNmzTBs2DD1+/fffx87d+4sdp9nzpzBpEmT1O99fHzw0ksvFdv2888/h0yW/7/Vmzdvonfv3oiOji7xWHJycrBmzRrcu3evxDbaNHr0aHzxxReIj48vtd2FCxewceNG9fuAgABdl0ZEVKvxwcdERKR1V65cQd++fSu0TefOnTFv3rwS148YMQKbN29GYGAgxo0bh4EDB8Le3h6PHz/Gli1bsGPHDnVbJycnfPnllyXua8WKFTh+/DhiY2ORk5ODIUOG4JVXXsErr7wCFxcXJCQkYM+ePVi3bp16lj5jY2P8/PPPMDAwKHafPXr0wAcffIAPP/wQAHDy5El4eHhgzJgx6NmzJ5ycnJCbm4sHDx7g1KlT2LlzJxISEnDp0qUKnafKiomJwXvvvYe5c+eiR4//b+/+XVIL4ziOf05gJHaEEFwOuTQpJQ2NQd5B2twd3J3aQpAGh/4LJ4fGhtoOhzhwxqYQcREURKegM8iBkMCGC5d7b+nt1n0ku+/X+vz6rh+eh+/zTYeHh9rd3VUqlZJlWRqPx/I8TxcXF5pOp5KkTCajSqWylPoA4KsicAEA/rkwDOW67l+t2djYWDh+fn6u+/t7+b6vVqulVqv16rxUKiXXdRc+hUun0/J9X8ViUePxWNL3p4OXl5evzrdtW9fX18rn8wtrbDQaWl9f19nZmWazmaIoUrPZVLPZXLhumZ6enuR5njzPWzgvnU7r6upKtm0vqTIA+Jp4UggAWAmxWEyu6+r09FSbm5svxi3LUqlU0t3dnfb29v64XzabVbvd1snJiRKJxNwzy+WyOp2OCoXCm+qs1+u6vb3V8fHx3NswSXIcR7VaTTs7O2/a96NqtZrK5fKLlva/s21b1WpVnU5H+/v7S6kNAL4ya7aKvWsBAP+Fn7sBDgaDH+3YoyjSzc2NhsOhoiiS4zg6OjrS9vb2u855fHxUEATq9/t6eHhQMplUJpNRoVBQMpl8d/1hGCoIAo1GI4VhqHg8LsdxlM/nlcvl3r3vR/V6PXW7XQ2HQ00mE62trWlra0u5XE4HBwe//FUGAPgYAhcA4NOaF7gAAFgVPCkEAAAAAEMIXAAAAABgCIELAAAAAAwhcAEAAACAIQQuAAAAADCEj48BAJ8WjXQBAKuOGy4AAAAAMITABQAAAACGELgAAAAAwBACFwAAAAAYQuACAAAAAEMIXAAAAABgCIELAAAAAAwhcAEAAACAIc+eQz/yzUcdbAAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt \n",
    "\n",
    "fig,ax = plt.subplots(1,1,figsize=(10,5))\n",
    "\n",
    "ax.set_title(\"Train and Validation Losses\",size=20)\n",
    "ax.set_ylabel('Loss', fontsize = 20) \n",
    "ax.set_xlabel('Epochs', fontsize = 25) \n",
    "_=ax.plot(train_losses)\n",
    "_=ax.plot(val_losses)\n",
    "_=ax.legend(('Train','Val'),loc='upper right')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:46:31.180351Z",
     "iopub.status.busy": "2023-11-05T11:46:31.179464Z",
     "iopub.status.idle": "2023-11-05T11:46:31.441180Z",
     "shell.execute_reply": "2023-11-05T11:46:31.440281Z",
     "shell.execute_reply.started": "2023-11-05T11:46:31.180316Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10, 5))\n",
    "plt.plot(range(1, epochs + 1), train_losses, label='Training Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.ylabel('Loss')\n",
    "plt.title('Training Loss Over Epochs')\n",
    "plt.legend()\n",
    "plt.grid(True)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:46:34.979463Z",
     "iopub.status.busy": "2023-11-05T11:46:34.978701Z",
     "iopub.status.idle": "2023-11-05T11:46:35.309925Z",
     "shell.execute_reply": "2023-11-05T11:46:35.309008Z",
     "shell.execute_reply.started": "2023-11-05T11:46:34.979429Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1cAAAHWCAYAAACbsXOkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAB2FUlEQVR4nO3dd3wUdf7H8fdueg8hHQKhh0QIKIKgQhAIICIIAgoqetYTC2LlRAE9K/ZynvoTET1EioB6CglIE1EUCSWh95JCAukk2WTn9weXlRhKgGw25fV8PPKQnfnuzmc/GdZ9MzPfMRmGYQgAAAAAcFHMji4AAAAAAOoDwhUAAAAAVAPCFQAAAABUA8IVAAAAAFQDwhUAAAAAVAPCFQAAAABUA8IVAAAAAFQDwhUAAAAAVAPCFQAAAABUA8IVANRy+/btk8lk0owZM2zLpkyZIpPJVKXnm0wmTZkypVpriouLU1xcXLW+JnA25X8PXnvtNUeXAgBnRLgCgGp0/fXXy9PTU3l5eWccM2bMGLm6uiorK6sGKzt/KSkpmjJlivbt2+foUmxWrFghk8mkefPmObqUKklOTtYtt9yiJk2ayM3NTeHh4RozZoySk5MdXVol5eHlTD8vv/yyo0sEgFrP2dEFAEB9MmbMGH377bdasGCBbrvttkrrCwsLtWjRIg0YMECNGze+4O1MmjRJTz311MWUek4pKSmaOnWq4uLiFBkZWWFdQkKCXbddH3z99de6+eabFRAQoDvvvFMtWrTQvn379Mknn2jevHmaPXu2brjhBkeXWcnNN9+sa6+9ttLyzp07O6AaAKhbCFcAUI2uv/56+fj4aNasWacNV4sWLVJBQYHGjBlzUdtxdnaWs7PjPsJdXV0dtu26YPfu3br11lvVsmVLrVq1SkFBQbZ1Dz/8sK6++mrdeuut2rRpk1q2bFljdRUUFMjLy+usYy699FLdcsstNVQRANQvnBYIANXIw8NDw4YN07Jly5SRkVFp/axZs+Tj46Prr79ex44d02OPPaYOHTrI29tbvr6+GjhwoDZu3HjO7Zzumqvi4mI98sgjCgoKsm3j0KFDlZ67f/9+3X///WrXrp08PDzUuHFjjRgxosLpfzNmzNCIESMkSb1797adGrZixQpJp7/mKiMjQ3feeadCQkLk7u6u2NhYffbZZxXGnHrdzEcffaRWrVrJzc1Nl19+uX777bdzvu+q2rNnj0aMGKGAgAB5enrqiiuu0H//+99K4959913FxMTI09NTjRo1UpcuXTRr1izb+ry8PI0fP16RkZFyc3NTcHCw+vXrpz/++OOs2582bZoKCwv10UcfVQhWkhQYGKgPP/xQBQUFevXVVyVJ8+bNk8lk0sqVKyu91ocffiiTyaQtW7bYlm3btk033nijAgIC5O7uri5duuibb76p8LwZM2bYXvP+++9XcHCwmjZteu7mVUFkZKSuu+46JSQkqFOnTnJ3d1d0dLS+/vrrSmOr+rsoKirSlClT1LZtW7m7uyssLEzDhg3T7t27K409176TlpamO+64Q02bNpWbm5vCwsI0ZMiQWnWKK4D6iSNXAFDNxowZo88++0xz5szRAw88YFt+7NgxLVmyRDfffLM8PDyUnJyshQsXasSIEWrRooXS09P14YcfqlevXkpJSVF4ePh5bfeuu+7SF198odGjR6tHjx768ccfNWjQoErjfvvtN/3888+66aab1LRpU+3bt08ffPCB4uLilJKSIk9PT/Xs2VMPPfSQ3nnnHf3jH/9Q+/btJcn23786ceKE4uLitGvXLj3wwANq0aKF5s6dq9tvv13Z2dl6+OGHK4yfNWuW8vLydO+998pkMunVV1/VsGHDtGfPHrm4uJzX+/6r9PR09ejRQ4WFhXrooYfUuHFjffbZZ7r++us1b94826l4H3/8sR566CHdeOONevjhh1VUVKRNmzbp119/1ejRoyVJ9913n+bNm6cHHnhA0dHRysrK0k8//aStW7fq0ksvPWMN3377rSIjI3X11Vefdn3Pnj0VGRlpCxmDBg2St7e35syZo169elUY+9VXXykmJkaXXHKJpJPXcV155ZVq0qSJnnrqKXl5eWnOnDkaOnSo5s+fX+lUw/vvv19BQUF69tlnVVBQcM7+FRYWKjMzs9Jyf3//CkdLd+7cqVGjRum+++7T2LFj9emnn2rEiBFavHix+vXrJ6nqv4uysjJdd911WrZsmW666SY9/PDDysvLU2JiorZs2aJWrVrZtluVfWf48OFKTk7Wgw8+qMjISGVkZCgxMVEHDhyodIorAFQrAwBQrUpLS42wsDCje/fuFZb/+9//NiQZS5YsMQzDMIqKioyysrIKY/bu3Wu4ubkZzz33XIVlkoxPP/3Utmzy5MnGqR/h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plba7tGjR89aV3U6cuSIFixYYHucm5urmTNnqlOnTgoNDZVU9d/F8OHDlZmZqffee6/Sds73aGZhYaGKiooqLGvVqpV8fHzO+XsDgIvFkSsAsJMWLVqoR48eWrRokSRVClfXXXednnvuOd1xxx3q0aOHNm/erP/85z8XdFPZTp066eabb9a//vUv5eTkqEePHlq2bJl27dpVaex1112nzz//XH5+foqOjtbatWu1dOlSNW7cuNJrOjk56ZVXXlFOTo7c3Nx0zTXXKDg4uNJr3nPPPfrwww91++23a/369YqMjNS8efO0Zs0avfXWW+ec3OF8zZ8/33b041Rjx47VU089pS+//FIDBw7UQw89pICAAH322Wfau3ev5s+fbzuyFh8fr9DQUF155ZUKCQnR1q1b9d5772nQoEHy8fFRdna2mjZtqhtvvFGxsbHy9vbW0qVL9dtvv1U46nc6bdq00WeffaYxY8aoQ4cOuvPOO9WiRQvt27dPn3zyiTIzM/Xll19WukbOxcVFw4YN0+zZs1VQUKDXXnut0mu///77uuqqq9ShQwfdfffdatmypdLT07V27VodOnSoSvdJO5s//vjjtEd3WrVqpe7du9set23bVnfeead+++03hYSEaPr06UpPT9enn35qG1PV38Vtt92mmTNnasKECVq3bp2uvvpqFRQUaOnSpbr//vs1ZMiQKte/Y8cO9enTRyNHjlR0dLScnZ21YMECpaen66abbrqIzgBAFThqmkIAaAjef/99Q5LRtWvXSuuKioqMRx991AgLCzM8PDyMK6+80li7dm2lac6rMhW7YRjGiRMnjIceesho3Lix4eXlZQwePNg4ePBgpanYjx8/btxxxx1GYGCg4e3tbfTv39/Ytm2b0bx5c2Ps2LEVXvPjjz82WrZsaTg5OVWYlv2vNRqGYaSnp9te19XV1ejQoUOFmk99L6ebJvuvdZ5O+VTsZ/opn/J79+7dxo033mj4+/sb7u7uRteuXY3vvvuuwmt9+OGHRs+ePY3GjRsbbm5uRqtWrYzHH3/cyMnJMQzDMIqLi43HH3/ciI2NNXx8fAwvLy8jNjbW+Ne//nXWGk+1adMm4+abbzbCwsIMFxcXIzQ01Lj55puNzZs3n/E5iYmJhiTDZDIZBw8ePO2Y3bt3G7fddpsRGhpquLi4GE2aNDGuu+46Y968ebYx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Xr16qUuXLjpx4oQeeOABrVixQvv379eaNWv022+/qX379pKk8ePHa8mSJdq7d6/++OMPLV++3LYOAACgISiylOmlH7ZqxL/Xal9WocL83PX5nV31/NBLqjRJW23n0HA1cOBA/fOf/9QNN9xQpfFvvfWWnnjiCV1++eVq06aNXnzxRbVp00bffvutbcwbb7yhu+++W3fccYeio6P173//W56enpo+fbq93kadc+edd+r48ePq379/heujJk2apEsvvVT9+/dXXFycQkNDNXTo0Cq/rtls1oIFC3TixAl17dpVd911l1544YUKY66//no98sgjeuCBB9SpUyf9/PPPeuaZZyqMGT58uAYMGKDevXsrKCjotNPBe3p6asmSJTp27Jguv/xy3XjjjerTp4/ee++982vGaeTn56tz584VfgYPHiyTyaRFixapUaNG6tmzp/r27auWLVvqq6++kiQ5OTkpKytLt912m9q2bauRI0dq4MCBmjp1qqSToW3cuHFq3769BgwYoLZt2+pf//rXRdcLAABQF2w5nKPr3/tJH67cI6shDb+0qRaP76mr2wQ5urRqYzKqeqMkOzOZTFqwYMF5fZm3Wq2KjIzUE088oQceeEAlJSXy9PTUvHnzKrzO2LFjlZ2drUWLFp32dYqLiyscHcnNzVVERIQyMzMrTbRQVFSkgwcP2k47rAmGYSgvL08+Pj7nfY0Vzq029reoqEj79u1TREREje1n9mKxWJSYmKh+/fpVugYOF4/+2hf9tS/6a1/0177ob9VZyqz6cNVevb9ij0qthhp7uer566PVLzr4zM+pRf3Nzc1VYGCgcnJyzjkJW50+9vbaa68pPz9fI0eOlCRlZmaqrKys0mlhISEh2rZt2xlf56WXXrIdXThVQkJCpZnyyqcIz8/Pt9skDGeSl5dXo9traGpTf0tKSnTixAmtWrVKpaV18Pbkp3G6G0qj+tBf+6K/9kV/7Yv+2hf9Pbu0QumLXU46WHDyH7BjA6wa2bJQln2/6/t9535+behvYWFhlcfW2XA1a9YsTZ06VYsWLVJw8JlTb1VMnDhREyZMsD0uP3IVHx9/xiNX3t7eHLmqJ2pjf4uKiuTh4aGePXty5ApnRX/ti/7aF/21L/prX/T37KxWQzPW7tfrv+1SSalVvu7Omnxdew3uGFql71u1qb+5ublVHlsnw9Xs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FB8fr8OHD1cYN2DAgAr78Jdffmnvt1PrXEh/JcnX17dC7/bv319hPfvwSRfS36+//rpCb7ds2SInJ6dKn8Hsv1LTpk318ssva/369fr99991zTXXaMiQIUpOTj7t+Dr9+WvAYSQZCxYsOOuYJ554woiJiamwbNSoUUb//v1tj7t27WqMGzfO9risrMwIDw83XnrppWqtt66pSn9PJzo62pg6dart8eTJk43Y2NjqK6yeqEp/ly9fbkgyjh8/fsYx7L+ndyH774IFCwyTyWTs27fPtoz99/QyMjIMScbKlSvPOGbkyJHGoEGDKizr1q2bce+99xqGYRhWq9UIDQ01pk2bZlufnZ1tuLm5GV9++aV9Cq9DqtLjvyotLTV8fHyMzz77zLZs7NixxpAhQ+xQYd1Wlf5++umnhp+f3xnXsw+f2YXsv2+++abh4+Nj5Ofn25ax/55Zo0aNjP/7v/877bq6/PnLkatabu3aterbt2+FZf3799fatWslSSUlJVq/fn2FMWazWX379rWNQdVZrVbl5eUpICCgwvKdO3cqPDxcLVu21JgxY3TgwAEHVVg3derUSWFhYerXr5/WrFljW87+W70++eQT9e3bV82bN6+wnP23spycHEmq9Hf9VOf6/N27d6/S0tIqjPHz81O3bt3Yf1W1Hv9VYWGhLBZLpeesWLFCwcHBateunf7+978rKyurWmuti6ra3/z8fDVv3lwRERGVjhSwD5/Zhey/n3zyiW666SZ5eXlVWM7+W1FZWZlmz56tgoICde/e/bRj6vLnL+GqlktLS1NISEiFZSEhIcrNzdWJEyeUmZmpsrKy047563UtOLfXXntN+fn5GjlypG1Zt27dNGPGDC1evFgffPCB9u7dq6uvvlp5eXkOrLRuCAsL07///W/Nnz9f8+fPV0REhOLi4vTHH39IEvtvNTpy5Ih++OEH3XXXXRWWs/9WZrVaNX78eF155ZW65JJLzjjuTJ+/5ftm+X/Zfyurao//6sknn1R4eHiFL0wDBgzQzJkztWzZMr3yyitauXKlBg4cqLKyMnuUXidUtb/t2rXT9OnTtWjRIn3xxReyWq3q0aOHDh06JIl9+EwuZP9dt26dtmzZUukzmP33T5s3b5a3t7fc3Nx03333acGCBYqOjj7t2Lr8+evs0K0DtcisWbM0depULVq0qMI1QQMHDrT9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",
      "text/plain": [
       "<Figure size 1000x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(10, 5))\n",
    "plt.plot(range(1, epochs + 1), val_losses, label='Validation Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.ylabel('Loss')\n",
    "plt.title('Validation Loss Over Epochs')\n",
    "plt.legend()\n",
    "plt.grid(True)\n",
    "\n",
    "# Show the plots\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Model training summary:-**\n",
    "I have to mention that I waited several hours to run all the notebook (sometimes ~9 hours) and it was a very tiring and frustrating process, because sometimes after i.e 8 hours my kaggle session was disconnected or my gpu is run out. So, what I was left with from the whole process, is that it is very time consuming to train the model and it needs a strong computing power.\n",
    "\n",
    "Nevertheless, I manage to run it for some hyperparameters that I want in order to take the best performance I could. I consulted the lectures of BERT for the values I want to try. More specifically:\n",
    "\n",
    "****Batch size:*** 8, 16\n",
    "\n",
    "***Learning rate (Adam)**:* 5e−5, 3e−5, 2e−5\n",
    "\n",
    "***Number of epochs**:* 2, 3, 4\n",
    "\n",
    "I will analyze it more later, but in the end I kept the values of *8 batch size, 3 epochs* and *5e-5 learning rate* for optimal hyperparameters."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 13:* Save trained model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:38:47.981112Z",
     "iopub.status.busy": "2023-11-05T12:38:47.979990Z",
     "iopub.status.idle": "2023-11-05T12:38:50.376618Z",
     "shell.execute_reply": "2023-11-05T12:38:50.375358Z",
     "shell.execute_reply.started": "2023-11-05T12:38:47.981076Z"
    }
   },
   "outputs": [],
   "source": [
    "# Save model to Google Drive\n",
    "torch.save(model, '/kaggle/working/bert_finetunedmodel')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 14:* Load trained model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:48:28.381398Z",
     "iopub.status.busy": "2023-11-05T11:48:28.381037Z",
     "iopub.status.idle": "2023-11-05T11:48:28.650062Z",
     "shell.execute_reply": "2023-11-05T11:48:28.649171Z",
     "shell.execute_reply.started": "2023-11-05T11:48:28.381366Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "BertForQuestionAnswering(\n",
       "  (bert): BertModel(\n",
       "    (embeddings): BertEmbeddings(\n",
       "      (word_embeddings): Embedding(30522, 768, padding_idx=0)\n",
       "      (position_embeddings): Embedding(512, 768)\n",
       "      (token_type_embeddings): Embedding(2, 768)\n",
       "      (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "      (dropout): Dropout(p=0.1, inplace=False)\n",
       "    )\n",
       "    (encoder): BertEncoder(\n",
       "      (layer): ModuleList(\n",
       "        (0-11): 12 x BertLayer(\n",
       "          (attention): BertAttention(\n",
       "            (self): BertSelfAttention(\n",
       "              (query): Linear(in_features=768, out_features=768, bias=True)\n",
       "              (key): Linear(in_features=768, out_features=768, bias=True)\n",
       "              (value): Linear(in_features=768, out_features=768, bias=True)\n",
       "              (dropout): Dropout(p=0.1, inplace=False)\n",
       "            )\n",
       "            (output): BertSelfOutput(\n",
       "              (dense): Linear(in_features=768, out_features=768, bias=True)\n",
       "              (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "              (dropout): Dropout(p=0.1, inplace=False)\n",
       "            )\n",
       "          )\n",
       "          (intermediate): BertIntermediate(\n",
       "            (dense): Linear(in_features=768, out_features=3072, bias=True)\n",
       "            (intermediate_act_fn): GELUActivation()\n",
       "          )\n",
       "          (output): BertOutput(\n",
       "            (dense): Linear(in_features=3072, out_features=768, bias=True)\n",
       "            (LayerNorm): LayerNorm((768,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (qa_outputs): Linear(in_features=768, out_features=2, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bert_model2 = torch.load('/kaggle/working/bert_finetunedmodel',map_location=torch.device('cpu'))\n",
    "bert_model2.eval()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 15:* Make the prediction and evaluate it "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:51:04.933941Z",
     "iopub.status.busy": "2023-11-05T11:51:04.933086Z",
     "iopub.status.idle": "2023-11-05T11:51:04.945683Z",
     "shell.execute_reply": "2023-11-05T11:51:04.944771Z",
     "shell.execute_reply.started": "2023-11-05T11:51:04.933907Z"
    }
   },
   "outputs": [],
   "source": [
    "def predict(context,query):\n",
    "    \n",
    "    inputs = tokenizer.encode_plus(query, context, return_tensors='pt')\n",
    "    outputs = bert_model2(**inputs)\n",
    "    answer_start = torch.argmax(outputs[0])  # get the most likely beginning of answer with the argmax of the score\n",
    "    answer_end = torch.argmax(outputs[1]) + 1 \n",
    "    answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(inputs['input_ids'][0][answer_start:answer_end]))\n",
    "    return answer\n",
    "\n",
    "def normalize_text(s):\n",
    "    \"\"\"Removing articles and punctuation, and standardizing whitespace are all typical text processing steps.\"\"\"\n",
    "    import string, re\n",
    "    def remove_articles(text):\n",
    "        regex = re.compile(r\"\\b(a|an|the)\\b\", re.UNICODE)\n",
    "        return re.sub(regex, \" \", text)\n",
    "    \n",
    "    def white_space_fix(text):\n",
    "        return \" \".join(text.split())\n",
    "    \n",
    "    def remove_punc(text):\n",
    "        exclude = set(string.punctuation)\n",
    "        return \"\".join(ch for ch in text if ch not in exclude)\n",
    "    \n",
    "    def lower(text):\n",
    "        return text.lower()\n",
    "    \n",
    "    return white_space_fix(remove_articles(remove_punc(lower(s))))\n",
    "\n",
    "def compute_exact_match(prediction, truth):\n",
    "    return int(normalize_text(prediction) == normalize_text(truth))\n",
    "\n",
    "def compute_f1(prediction, truth):\n",
    "    pred_tokens = normalize_text(prediction).split()\n",
    "    truth_tokens = normalize_text(truth).split()\n",
    "\n",
    "    # if either the prediction or the truth is no-answer then f1 = 1 if they agree, 0 otherwise\n",
    "    if len(pred_tokens) == 0 or len(truth_tokens) == 0:\n",
    "        return int(pred_tokens == truth_tokens)\n",
    "    \n",
    "    common_tokens = set(pred_tokens) & set(truth_tokens)\n",
    "    \n",
    "    # if there are no common tokens then f1 = 0\n",
    "    if len(common_tokens) == 0:\n",
    "        return 0\n",
    "    \n",
    "    prec = len(common_tokens) / len(pred_tokens)\n",
    "    rec = len(common_tokens) / len(truth_tokens)\n",
    "    return 2 * (prec * rec) / (prec + rec)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:51:12.860189Z",
     "iopub.status.busy": "2023-11-05T11:51:12.859371Z",
     "iopub.status.idle": "2023-11-05T11:51:12.865841Z",
     "shell.execute_reply": "2023-11-05T11:51:12.864795Z",
     "shell.execute_reply.started": "2023-11-05T11:51:12.860152Z"
    }
   },
   "outputs": [],
   "source": [
    "def give_an_answer(context,query,answer):\n",
    "    prediction = predict(context,query)\n",
    "    em_score = compute_exact_match(prediction, answer)\n",
    "    f1_score = compute_f1(prediction, answer)\n",
    "    print(f\"Question: {query}\")\n",
    "    print(f\"Prediction: {prediction}\")\n",
    "    print(f\"True Answer: {answer}\")\n",
    "    print(f\"EM: {em_score}\")\n",
    "    print(f\"F1: {f1_score}\")\n",
    "    print(\"\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 16:* Test my trained model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here I give some examples to my trained BERT model on SQuAD 2.0 dataset to see how well I trained it. I started with more easier examples and then I gave it more complex ones.\n",
    "\n",
    "For extractive textual QA tasks, we usually adopt two evaluation metrics, which measure ***exact match*** and partially ***overlapped scores*** respectively.\n",
    "\n",
    "***Exact Match***: measures whether the predicted answer exactly matches the ground-truth answers. If the exact matching occurs, then assigns 1.0, otherwise assigns 0.0.\n",
    "\n",
    "***F1 Score***: computes the average word overlap between predicted and ground-truth answers, which can ensure both of precision and recall rate are optimized at the same time.\n",
    "\n",
    "**As you can see my model predicted all the answers correct in a very small an easy example.**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:51:15.307834Z",
     "iopub.status.busy": "2023-11-05T11:51:15.307436Z",
     "iopub.status.idle": "2023-11-05T11:51:15.708394Z",
     "shell.execute_reply": "2023-11-05T11:51:15.707288Z",
     "shell.execute_reply.started": "2023-11-05T11:51:15.307803Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: How old is Alexa?\n",
      "Prediction: 21\n",
      "True Answer: 21\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Where does Alexa live now?\n",
      "Prediction: kaisariani\n",
      "True Answer: Kaisariani of Athens\n",
      "EM: 0\n",
      "F1: 0.5\n",
      "\n",
      "\n",
      "Question: Where Alexa used to live?\n",
      "Prediction: peristeri of athens,\n",
      "True Answer: Peristeri of Athens\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"Hi! My name is Alexa and I am 21 years old. I used to live in Peristeri of Athens, but now I moved on in Kaisariani of Athens.\"\n",
    "\n",
    "queries = [\"How old is Alexa?\",\n",
    "           \"Where does Alexa live now?\",\n",
    "           \"Where Alexa used to live?\"\n",
    "          ]\n",
    "answers = [\"21\",\n",
    "           \"Kaisariani of Athens\",\n",
    "           \"Peristeri of Athens\"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "    give_an_answer(context,q,a)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:53:09.862573Z",
     "iopub.status.busy": "2023-11-05T11:53:09.862187Z",
     "iopub.status.idle": "2023-11-05T11:53:10.303826Z",
     "shell.execute_reply": "2023-11-05T11:53:10.302875Z",
     "shell.execute_reply.started": "2023-11-05T11:53:09.862542Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: When did Queen found?\n",
      "Prediction: 1970.\n",
      "True Answer: 1970\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Who were the basic members of Queen band?\n",
      "Prediction: freddie mercury ( lead vocals, piano ), brian may ( guitar, vocals ), roger taylor ( drums, vocals ) and john deacon ( bass ).\n",
      "True Answer: Freddie Mercury, Brian May, Roger Taylor and John Deacon\n",
      "EM: 0\n",
      "F1: 0.6923076923076924\n",
      "\n",
      "\n",
      "Question: What kind of band they are?\n",
      "Prediction: rock\n",
      "True Answer: rock\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"\"\" Queen are a British rock band formed in London in 1970. Their classic line-up was Freddie Mercury (lead vocals, piano), \n",
    "            Brian May (guitar, vocals), Roger Taylor (drums, vocals) and John Deacon (bass). Their earliest works were influenced \n",
    "            by progressive rock, hard rock and heavy metal, but the band gradually ventured into more conventional and radio-friendly \n",
    "            works by incorporating further styles, such as arena rock and pop rock. \"\"\"\n",
    "\n",
    "queries = [\"When did Queen found?\",\n",
    "           \"Who were the basic members of Queen band?\",\n",
    "           \"What kind of band they are?\"\n",
    "          ]\n",
    "answers = [\"1970\",\n",
    "           \"Freddie Mercury, Brian May, Roger Taylor and John Deacon\",\n",
    "           \"rock\"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "    give_an_answer(context,q,a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T11:56:00.967048Z",
     "iopub.status.busy": "2023-11-05T11:56:00.966670Z",
     "iopub.status.idle": "2023-11-05T11:56:01.567798Z",
     "shell.execute_reply": "2023-11-05T11:56:01.567030Z",
     "shell.execute_reply.started": "2023-11-05T11:56:00.967018Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: How many metres is Olympus?\n",
      "Prediction: \n",
      "True Answer: 2917\n",
      "EM: 0\n",
      "F1: 0\n",
      "\n",
      "\n",
      "Question: Where Olympus is near?\n",
      "Prediction: gulf of thermai of the aegean sea,\n",
      "True Answer: Gulf of Thérmai of the Aegean Sea\n",
      "EM: 0\n",
      "F1: 0.6666666666666666\n",
      "\n",
      "\n",
      "Question: How far away is Olympus from Thessaloniki?\n",
      "Prediction: 80 km\n",
      "True Answer: 80 km (50 mi)\n",
      "EM: 0\n",
      "F1: 0.6666666666666666\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"\"\" Mount Olympus is the highest mountain in Greece. It is part of the Olympus massif near \n",
    "              the Gulf of Thérmai of the Aegean Sea, located in the Olympus Range on the border between \n",
    "              Thessaly and Macedonia, between the regional units of Pieria and Larissa, about 80 km (50 mi) \n",
    "              southwest from Thessaloniki. Mount Olympus has 52 peaks and deep gorges. The highest peak, \n",
    "              Mytikas, meaning \"nose\", rises to 2917 metres (9,570 ft). It is one of the \n",
    "              highest peaks in Europe in terms of topographic prominence. \"\"\"\n",
    "\n",
    "queries = [\n",
    "           \"How many metres is Olympus?\",\n",
    "           \"Where Olympus is near?\",\n",
    "           \"How far away is Olympus from Thessaloniki?\"\n",
    "          ]\n",
    "answers = [\n",
    "           \"2917\",\n",
    "           \"Gulf of Thérmai of the Aegean Sea\",\n",
    "           \"80 km (50 mi)\"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "    give_an_answer(context,q,a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:02:08.808163Z",
     "iopub.status.busy": "2023-11-05T12:02:08.807764Z",
     "iopub.status.idle": "2023-11-05T12:02:11.725583Z",
     "shell.execute_reply": "2023-11-05T12:02:11.724662Z",
     "shell.execute_reply.started": "2023-11-05T12:02:08.808109Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: What is COVID-19?\n",
      "Prediction: coronavirus disease 2019\n",
      "True Answer: an ongoing pandemic of coronavirus disease 2019\n",
      "EM: 0\n",
      "F1: 0.6666666666666666\n",
      "\n",
      "\n",
      "Question: What is caused by COVID-19?\n",
      "Prediction: severe acute respiratory syndrome coronavirus 2\n",
      "True Answer: severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2)\n",
      "EM: 0\n",
      "F1: 0.923076923076923\n",
      "\n",
      "\n",
      "Question: How many cases have been confirmed from COVID-19?\n",
      "Prediction: more than 105 million\n",
      "True Answer: more than 105 million cases\n",
      "EM: 0\n",
      "F1: 0.888888888888889\n",
      "\n",
      "\n",
      "Question: How many deaths have been confirmed from COVID-19?\n",
      "Prediction: 2. 3 million\n",
      "True Answer: more than 2.3 million deaths\n",
      "EM: 0\n",
      "F1: 0.25\n",
      "\n",
      "\n",
      "Question: How is COVID-19 spread?\n",
      "Prediction: mainly through the air when people are near each other.\n",
      "True Answer: mainly through the air when people are near each other. It leaves an infected person as they breathe, cough, sneeze, or speak and enters another person via their mouth, nose, or eyes. It may also spread via contaminated surfaces.\n",
      "EM: 0\n",
      "F1: 0.391304347826087\n",
      "\n",
      "\n",
      "Question: How long can an infected person remain infected?\n",
      "Prediction: two weeks\n",
      "True Answer: up to two weeks\n",
      "EM: 0\n",
      "F1: 0.6666666666666666\n",
      "\n",
      "\n",
      "Question: Can a infected person spread the virus even if they don't have symptoms?\n",
      "Prediction: \n",
      "True Answer: yes\n",
      "EM: 0\n",
      "F1: 0\n",
      "\n",
      "\n",
      "Question: What do elephants eat?\n",
      "Prediction: elephants\n",
      "True Answer:  \n",
      "EM: 0\n",
      "F1: 0\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"\"\" The COVID-19 pandemic, also known as the coronavirus pandemic, is an ongoing pandemic of coronavirus disease 2019 (COVID-19) \n",
    "              caused by severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2). It was first identified in December 2019 in Wuhan, China. \n",
    "              The World Health Organization declared the outbreak a Public Health Emergency of International Concern in January 2020 and a pandemic \n",
    "              in March 2020. As of 6 February 2021, more than 105 million cases have been confirmed, with more than 2.3 million deaths attributed to COVID-19.\n",
    "              Symptoms of COVID-19 are highly variable, ranging from none to severe illness. The virus spreads mainly through the air when people are \n",
    "              near each other.[b] It leaves an infected person as they breathe, cough, sneeze, or speak and enters another person via their mouth, nose, or eyes. \n",
    "              It may also spread via contaminated surfaces. People remain infectious for up to two weeks, and can spread the virus even if they do not show symptoms.[9]\"\"\"\n",
    "\n",
    "queries = [\n",
    "           \"What is COVID-19?\",\n",
    "           \"What is caused by COVID-19?\",\n",
    "           \"How many cases have been confirmed from COVID-19?\",\n",
    "           \"How many deaths have been confirmed from COVID-19?\",\n",
    "           \"How is COVID-19 spread?\",\n",
    "           \"How long can an infected person remain infected?\",\n",
    "           \"Can a infected person spread the virus even if they don't have symptoms?\",\n",
    "           \"What do elephants eat?\"\n",
    "          ]\n",
    "answers = [\n",
    "           \"an ongoing pandemic of coronavirus disease 2019\",\n",
    "           \"severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2)\",\n",
    "           \"more than 105 million cases\",\n",
    "           \"more than 2.3 million deaths\",\n",
    "           \"mainly through the air when people are near each other. It leaves an infected person as they breathe, cough, sneeze, or speak and enters another person via their mouth, nose, or eyes. It may also spread via contaminated surfaces.\",\n",
    "           \"up to two weeks\",\n",
    "           \"yes\",\n",
    "           \" \"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "      give_an_answer(context,q,a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:04:19.581560Z",
     "iopub.status.busy": "2023-11-05T12:04:19.580228Z",
     "iopub.status.idle": "2023-11-05T12:04:22.039443Z",
     "shell.execute_reply": "2023-11-05T12:04:22.038488Z",
     "shell.execute_reply.started": "2023-11-05T12:04:19.581499Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: Who wrote Harry Potter's novels?\n",
      "Prediction: j. k. rowling.\n",
      "True Answer: J. K. Rowling\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Who are Harry Potter's friends?\n",
      "Prediction: hermione granger and ron weasley,\n",
      "True Answer: Hermione Granger and Ron Weasley\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Who is the enemy of Harry Potter?\n",
      "Prediction: j. k. rowling.\n",
      "True Answer: Lord Voldemort\n",
      "EM: 0\n",
      "F1: 0\n",
      "\n",
      "\n",
      "Question: What are Muggles?\n",
      "Prediction: non - magical people )\n",
      "True Answer: non-magical people\n",
      "EM: 0\n",
      "F1: 0.4\n",
      "\n",
      "\n",
      "Question: Which is the name of Harry Poter's first novel?\n",
      "Prediction: \n",
      "True Answer: Harry Potter and the Philosopher's Stone\n",
      "EM: 0\n",
      "F1: 0\n",
      "\n",
      "\n",
      "Question: When did the first novel release?\n",
      "Prediction: 26 june 1997,\n",
      "True Answer: 26 June 1997\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Who was attracted by Harry Potter novels?\n",
      "Prediction: j. k. rowling. the novels chronicle the lives of a young wizard, harry potter, and his friends hermione granger and ron weasley,\n",
      "True Answer: a wide adult audience as well as younger readers\n",
      "EM: 0\n",
      "F1: 0\n",
      "\n",
      "\n",
      "Question: How many languages Harry Potter has been translated into? \n",
      "Prediction: eighty\n",
      "True Answer: eighty\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"\"\" Harry Potter is a series of seven fantasy novels written by British author, J. K. Rowling. The novels chronicle the lives of a young wizard, \n",
    "              Harry Potter, and his friends Hermione Granger and Ron Weasley, all of whom are students at Hogwarts School of Witchcraft and Wizardry. \n",
    "              The main story arc concerns Harry's struggle against Lord Voldemort, a dark wizard who intends to become immortal, overthrow the wizard \n",
    "              governing body known as the Ministry of Magic and subjugate all wizards and Muggles (non-magical people). Since the release of the first novel, \n",
    "              Harry Potter and the Philosopher's Stone, on 26 June 1997, the books have found immense popularity, positive reviews, and commercial success worldwide. \n",
    "              They have attracted a wide adult audience as well as younger readers and are often considered cornerstones of modern young adult literature.[2] \n",
    "              As of February 2018, the books have sold more than 500 million copies worldwide, making them the best-selling book series in history, and have been translated \n",
    "              into eighty languages.[3] The last four books consecutively set records as the fastest-selling books in history, with the final installment selling roughly \n",
    "              eleven million copies in the United States within twenty-four hours of its release.  \"\"\"\n",
    "\n",
    "queries = [\n",
    "           \"Who wrote Harry Potter's novels?\",\n",
    "           \"Who are Harry Potter's friends?\",\n",
    "           \"Who is the enemy of Harry Potter?\",\n",
    "           \"What are Muggles?\",\n",
    "           \"Which is the name of Harry Poter's first novel?\",\n",
    "           \"When did the first novel release?\",\n",
    "           \"Who was attracted by Harry Potter novels?\",\n",
    "           \"How many languages Harry Potter has been translated into? \"\n",
    "          ]\n",
    "answers = [\n",
    "           \"J. K. Rowling\",\n",
    "           \"Hermione Granger and Ron Weasley\",\n",
    "           \"Lord Voldemort\",\n",
    "           \"non-magical people\",\n",
    "           \"Harry Potter and the Philosopher's Stone\",\n",
    "           \"26 June 1997\",\n",
    "           \"a wide adult audience as well as younger readers\",\n",
    "           \"eighty\"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "      give_an_answer(context,q,a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 17:* Test pretrained BERT model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:15:30.245813Z",
     "iopub.status.busy": "2023-11-05T12:15:30.245407Z",
     "iopub.status.idle": "2023-11-05T12:15:39.219079Z",
     "shell.execute_reply": "2023-11-05T12:15:39.218166Z",
     "shell.execute_reply.started": "2023-11-05T12:15:30.245783Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e9ee7d32b2ee43bdba12cd83473e4d19",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)okenizer_config.json:   0%|          | 0.00/28.0 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c571e0c397e64c8880e558b066bb51ae",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)lve/main/config.json:   0%|          | 0.00/443 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "28a959dc59a74c3dab262e254cc470cf",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)solve/main/vocab.txt:   0%|          | 0.00/232k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f1d6595f28d3418caba72b5b7cbf76c0",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)/main/tokenizer.json:   0%|          | 0.00/466k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "307a36be5e7b417d9c8fa4782ff72d23",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading model.safetensors:   0%|          | 0.00/1.34G [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "BertForQuestionAnswering(\n",
       "  (bert): BertModel(\n",
       "    (embeddings): BertEmbeddings(\n",
       "      (word_embeddings): Embedding(30522, 1024, padding_idx=0)\n",
       "      (position_embeddings): Embedding(512, 1024)\n",
       "      (token_type_embeddings): Embedding(2, 1024)\n",
       "      (LayerNorm): LayerNorm((1024,), eps=1e-12, elementwise_affine=True)\n",
       "      (dropout): Dropout(p=0.1, inplace=False)\n",
       "    )\n",
       "    (encoder): BertEncoder(\n",
       "      (layer): ModuleList(\n",
       "        (0-23): 24 x BertLayer(\n",
       "          (attention): BertAttention(\n",
       "            (self): BertSelfAttention(\n",
       "              (query): Linear(in_features=1024, out_features=1024, bias=True)\n",
       "              (key): Linear(in_features=1024, out_features=1024, bias=True)\n",
       "              (value): Linear(in_features=1024, out_features=1024, bias=True)\n",
       "              (dropout): Dropout(p=0.1, inplace=False)\n",
       "            )\n",
       "            (output): BertSelfOutput(\n",
       "              (dense): Linear(in_features=1024, out_features=1024, bias=True)\n",
       "              (LayerNorm): LayerNorm((1024,), eps=1e-12, elementwise_affine=True)\n",
       "              (dropout): Dropout(p=0.1, inplace=False)\n",
       "            )\n",
       "          )\n",
       "          (intermediate): BertIntermediate(\n",
       "            (dense): Linear(in_features=1024, out_features=4096, bias=True)\n",
       "            (intermediate_act_fn): GELUActivation()\n",
       "          )\n",
       "          (output): BertOutput(\n",
       "            (dense): Linear(in_features=4096, out_features=1024, bias=True)\n",
       "            (LayerNorm): LayerNorm((1024,), eps=1e-12, elementwise_affine=True)\n",
       "            (dropout): Dropout(p=0.1, inplace=False)\n",
       "          )\n",
       "        )\n",
       "      )\n",
       "    )\n",
       "  )\n",
       "  (qa_outputs): Linear(in_features=1024, out_features=2, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Define the bert tokenizer\n",
    "tokenizer = AutoTokenizer.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad')\n",
    "\n",
    "# Load the fine-tuned modeol\n",
    "model = BertForQuestionAnswering.from_pretrained('bert-large-uncased-whole-word-masking-finetuned-squad')\n",
    "model.eval()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:19:54.656856Z",
     "iopub.status.busy": "2023-11-05T12:19:54.656473Z",
     "iopub.status.idle": "2023-11-05T12:19:54.668855Z",
     "shell.execute_reply": "2023-11-05T12:19:54.667744Z",
     "shell.execute_reply.started": "2023-11-05T12:19:54.656823Z"
    }
   },
   "outputs": [],
   "source": [
    "def predict(context,query):\n",
    "    \n",
    "    inputs = tokenizer.encode_plus(query, context, return_tensors='pt')\n",
    "    outputs = model(**inputs)\n",
    "    answer_start = torch.argmax(outputs[0])  # get the most likely beginning of answer with the argmax of the score\n",
    "    answer_end = torch.argmax(outputs[1]) + 1 \n",
    "    answer = tokenizer.convert_tokens_to_string(tokenizer.convert_ids_to_tokens(inputs['input_ids'][0][answer_start:answer_end]))\n",
    "    return answer\n",
    "\n",
    "def normalize_text(s):\n",
    "    \"\"\"Removing articles and punctuation, and standardizing whitespace are all typical text processing steps.\"\"\"\n",
    "    import string, re\n",
    "    def remove_articles(text):\n",
    "        regex = re.compile(r\"\\b(a|an|the)\\b\", re.UNICODE)\n",
    "        return re.sub(regex, \" \", text)\n",
    "    \n",
    "    def white_space_fix(text):\n",
    "        return \" \".join(text.split())\n",
    "    \n",
    "    def remove_punc(text):\n",
    "        exclude = set(string.punctuation)\n",
    "        return \"\".join(ch for ch in text if ch not in exclude)\n",
    "    \n",
    "    def lower(text):\n",
    "        return text.lower()\n",
    "    \n",
    "    return white_space_fix(remove_articles(remove_punc(lower(s))))\n",
    "\n",
    "def compute_exact_match(prediction, truth):\n",
    "    return int(normalize_text(prediction) == normalize_text(truth))\n",
    "\n",
    "def compute_f1(prediction, truth):\n",
    "    pred_tokens = normalize_text(prediction).split()\n",
    "    truth_tokens = normalize_text(truth).split()\n",
    "\n",
    "    # if either the prediction or the truth is no-answer then f1 = 1 if they agree, 0 otherwise\n",
    "    if len(pred_tokens) == 0 or len(truth_tokens) == 0:\n",
    "        return int(pred_tokens == truth_tokens)\n",
    "    \n",
    "    common_tokens = set(pred_tokens) & set(truth_tokens)\n",
    "    \n",
    "    # if there are no common tokens then f1 = 0\n",
    "    if len(common_tokens) == 0:\n",
    "        return 0\n",
    "    \n",
    "    prec = len(common_tokens) / len(pred_tokens)\n",
    "    rec = len(common_tokens) / len(truth_tokens)\n",
    "    return 2 * (prec * rec) / (prec + rec)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:20:26.001632Z",
     "iopub.status.busy": "2023-11-05T12:20:26.001232Z",
     "iopub.status.idle": "2023-11-05T12:20:26.007656Z",
     "shell.execute_reply": "2023-11-05T12:20:26.006568Z",
     "shell.execute_reply.started": "2023-11-05T12:20:26.001600Z"
    }
   },
   "outputs": [],
   "source": [
    "def give_an_answer(context,query,answer):\n",
    "    prediction = predict(context,query)\n",
    "    em_score = compute_exact_match(prediction, answer)\n",
    "    f1_score = compute_f1(prediction, answer)\n",
    "    print(f\"Question: {query}\")\n",
    "    print(f\"Prediction: {prediction}\")\n",
    "    print(f\"True Answer: {answer}\")\n",
    "    print(f\"EM: {em_score}\")\n",
    "    print(f\"F1: {f1_score}\")\n",
    "    print(\"\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:21:15.597516Z",
     "iopub.status.busy": "2023-11-05T12:21:15.596895Z",
     "iopub.status.idle": "2023-11-05T12:21:16.633182Z",
     "shell.execute_reply": "2023-11-05T12:21:16.632215Z",
     "shell.execute_reply.started": "2023-11-05T12:21:15.597483Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: How old is Alexa?\n",
      "Prediction: 21\n",
      "True Answer: 21\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Where does Alexa live now?\n",
      "Prediction: kaisariani of athens\n",
      "True Answer: Kaisariani of Athens\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Where Alexa used to live?\n",
      "Prediction: peristeri of athens\n",
      "True Answer: Peristeri of Athens\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"Hi! My name is Alexa and I am 21 years old. I used to live in Peristeri of Athens, but now I moved on in Kaisariani of Athens.\"\n",
    "\n",
    "queries = [\"How old is Alexa?\",\n",
    "           \"Where does Alexa live now?\",\n",
    "           \"Where Alexa used to live?\"\n",
    "          ]\n",
    "answers = [\"21\",\n",
    "           \"Kaisariani of Athens\",\n",
    "           \"Peristeri of Athens\"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "    give_an_answer(context,q,a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:21:53.587436Z",
     "iopub.status.busy": "2023-11-05T12:21:53.586571Z",
     "iopub.status.idle": "2023-11-05T12:21:55.218956Z",
     "shell.execute_reply": "2023-11-05T12:21:55.217982Z",
     "shell.execute_reply.started": "2023-11-05T12:21:53.587405Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: When did Queen found?\n",
      "Prediction: 1970\n",
      "True Answer: 1970\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Who were the basic members of Queen band?\n",
      "Prediction: freddie mercury ( lead vocals, piano ), brian may ( guitar, vocals ), roger taylor ( drums, vocals ) and john deacon ( bass )\n",
      "True Answer: Freddie Mercury, Brian May, Roger Taylor and John Deacon\n",
      "EM: 0\n",
      "F1: 0.6923076923076924\n",
      "\n",
      "\n",
      "Question: What kind of band they are?\n",
      "Prediction: british rock\n",
      "True Answer: rock\n",
      "EM: 0\n",
      "F1: 0.6666666666666666\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"\"\" Queen are a British rock band formed in London in 1970. Their classic line-up was Freddie Mercury (lead vocals, piano), \n",
    "            Brian May (guitar, vocals), Roger Taylor (drums, vocals) and John Deacon (bass). Their earliest works were influenced \n",
    "            by progressive rock, hard rock and heavy metal, but the band gradually ventured into more conventional and radio-friendly \n",
    "            works by incorporating further styles, such as arena rock and pop rock. \"\"\"\n",
    "\n",
    "queries = [\"When did Queen found?\",\n",
    "           \"Who were the basic members of Queen band?\",\n",
    "           \"What kind of band they are?\"\n",
    "          ]\n",
    "answers = [\"1970\",\n",
    "           \"Freddie Mercury, Brian May, Roger Taylor and John Deacon\",\n",
    "           \"rock\"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "    give_an_answer(context,q,a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:23:04.826856Z",
     "iopub.status.busy": "2023-11-05T12:23:04.825929Z",
     "iopub.status.idle": "2023-11-05T12:23:12.676878Z",
     "shell.execute_reply": "2023-11-05T12:23:12.675913Z",
     "shell.execute_reply.started": "2023-11-05T12:23:04.826813Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: What is COVID-19?\n",
      "Prediction: an ongoing pandemic of coronavirus disease 2019\n",
      "True Answer: an ongoing pandemic of coronavirus disease 2019\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: What is caused by COVID-19?\n",
      "Prediction: coronavirus disease 2019\n",
      "True Answer: severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2)\n",
      "EM: 0\n",
      "F1: 0.2\n",
      "\n",
      "\n",
      "Question: How many cases have been confirmed from COVID-19?\n",
      "Prediction: more than 105 million\n",
      "True Answer: more than 105 million cases\n",
      "EM: 0\n",
      "F1: 0.888888888888889\n",
      "\n",
      "\n",
      "Question: How many deaths have been confirmed from COVID-19?\n",
      "Prediction: 2. 3 million\n",
      "True Answer: more than 2.3 million deaths\n",
      "EM: 0\n",
      "F1: 0.25\n",
      "\n",
      "\n",
      "Question: How is COVID-19 spread?\n",
      "Prediction: through the air when people are near each other\n",
      "True Answer: mainly through the air when people are near each other. It leaves an infected person as they breathe, cough, sneeze, or speak and enters another person via their mouth, nose, or eyes. It may also spread via contaminated surfaces.\n",
      "EM: 0\n",
      "F1: 0.35555555555555557\n",
      "\n",
      "\n",
      "Question: How long can an infected person remain infected?\n",
      "Prediction: up to two weeks\n",
      "True Answer: up to two weeks\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Can a infected person spread the virus even if they don't have symptoms?\n",
      "Prediction: can spread the virus even if they do not show symptoms\n",
      "True Answer: yes\n",
      "EM: 0\n",
      "F1: 0\n",
      "\n",
      "\n",
      "Question: What do elephants eat?\n",
      "Prediction: [SEP]\n",
      "True Answer:  \n",
      "EM: 0\n",
      "F1: 0\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"\"\" The COVID-19 pandemic, also known as the coronavirus pandemic, is an ongoing pandemic of coronavirus disease 2019 (COVID-19) \n",
    "              caused by severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2). It was first identified in December 2019 in Wuhan, China. \n",
    "              The World Health Organization declared the outbreak a Public Health Emergency of International Concern in January 2020 and a pandemic \n",
    "              in March 2020. As of 6 February 2021, more than 105 million cases have been confirmed, with more than 2.3 million deaths attributed to COVID-19.\n",
    "              Symptoms of COVID-19 are highly variable, ranging from none to severe illness. The virus spreads mainly through the air when people are \n",
    "              near each other.[b] It leaves an infected person as they breathe, cough, sneeze, or speak and enters another person via their mouth, nose, or eyes. \n",
    "              It may also spread via contaminated surfaces. People remain infectious for up to two weeks, and can spread the virus even if they do not show symptoms.[9]\"\"\"\n",
    "\n",
    "queries = [\n",
    "           \"What is COVID-19?\",\n",
    "           \"What is caused by COVID-19?\",\n",
    "           \"How many cases have been confirmed from COVID-19?\",\n",
    "           \"How many deaths have been confirmed from COVID-19?\",\n",
    "           \"How is COVID-19 spread?\",\n",
    "           \"How long can an infected person remain infected?\",\n",
    "           \"Can a infected person spread the virus even if they don't have symptoms?\",\n",
    "           \"What do elephants eat?\"\n",
    "          ]\n",
    "answers = [\n",
    "           \"an ongoing pandemic of coronavirus disease 2019\",\n",
    "           \"severe acute respiratory syndrome coronavirus 2 (SARS-CoV-2)\",\n",
    "           \"more than 105 million cases\",\n",
    "           \"more than 2.3 million deaths\",\n",
    "           \"mainly through the air when people are near each other. It leaves an infected person as they breathe, cough, sneeze, or speak and enters another person via their mouth, nose, or eyes. It may also spread via contaminated surfaces.\",\n",
    "           \"up to two weeks\",\n",
    "           \"yes\",\n",
    "           \" \"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "      give_an_answer(context,q,a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:25:43.306992Z",
     "iopub.status.busy": "2023-11-05T12:25:43.306101Z",
     "iopub.status.idle": "2023-11-05T12:25:51.575514Z",
     "shell.execute_reply": "2023-11-05T12:25:51.574568Z",
     "shell.execute_reply.started": "2023-11-05T12:25:43.306958Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Question: Who wrote Harry Potter's novels?\n",
      "Prediction: j. k. rowling\n",
      "True Answer: J. K. Rowling\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Who are Harry Potter's friends?\n",
      "Prediction: hermione granger and ron weasley\n",
      "True Answer: Hermione Granger and Ron Weasley\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Who is the enemy of Harry Potter?\n",
      "Prediction: lord voldemort\n",
      "True Answer: Lord Voldemort\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: What are Muggles?\n",
      "Prediction: non - magical people\n",
      "True Answer: non-magical people\n",
      "EM: 0\n",
      "F1: 0.4\n",
      "\n",
      "\n",
      "Question: Which is the name of Harry Poter's first novel?\n",
      "Prediction: harry potter and the philosopher ' s stone\n",
      "True Answer: Harry Potter and the Philosopher's Stone\n",
      "EM: 0\n",
      "F1: 0.7272727272727272\n",
      "\n",
      "\n",
      "Question: When did the first novel release?\n",
      "Prediction: 26 june 1997\n",
      "True Answer: 26 June 1997\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n",
      "Question: Who was attracted by Harry Potter novels?\n",
      "Prediction: wide adult audience as well as younger readers\n",
      "True Answer: a wide adult audience as well as younger readers\n",
      "EM: 1\n",
      "F1: 0.875\n",
      "\n",
      "\n",
      "Question: How many languages Harry Potter has been translated into? \n",
      "Prediction: eighty\n",
      "True Answer: eighty\n",
      "EM: 1\n",
      "F1: 1.0\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "context = \"\"\" Harry Potter is a series of seven fantasy novels written by British author, J. K. Rowling. The novels chronicle the lives of a young wizard, \n",
    "              Harry Potter, and his friends Hermione Granger and Ron Weasley, all of whom are students at Hogwarts School of Witchcraft and Wizardry. \n",
    "              The main story arc concerns Harry's struggle against Lord Voldemort, a dark wizard who intends to become immortal, overthrow the wizard \n",
    "              governing body known as the Ministry of Magic and subjugate all wizards and Muggles (non-magical people). Since the release of the first novel, \n",
    "              Harry Potter and the Philosopher's Stone, on 26 June 1997, the books have found immense popularity, positive reviews, and commercial success worldwide. \n",
    "              They have attracted a wide adult audience as well as younger readers and are often considered cornerstones of modern young adult literature.[2] \n",
    "              As of February 2018, the books have sold more than 500 million copies worldwide, making them the best-selling book series in history, and have been translated \n",
    "              into eighty languages.[3] The last four books consecutively set records as the fastest-selling books in history, with the final installment selling roughly \n",
    "              eleven million copies in the United States within twenty-four hours of its release.  \"\"\"\n",
    "\n",
    "queries = [\n",
    "           \"Who wrote Harry Potter's novels?\",\n",
    "           \"Who are Harry Potter's friends?\",\n",
    "           \"Who is the enemy of Harry Potter?\",\n",
    "           \"What are Muggles?\",\n",
    "           \"Which is the name of Harry Poter's first novel?\",\n",
    "           \"When did the first novel release?\",\n",
    "           \"Who was attracted by Harry Potter novels?\",\n",
    "           \"How many languages Harry Potter has been translated into? \"\n",
    "          ]\n",
    "answers = [\n",
    "           \"J. K. Rowling\",\n",
    "           \"Hermione Granger and Ron Weasley\",\n",
    "           \"Lord Voldemort\",\n",
    "           \"non-magical people\",\n",
    "           \"Harry Potter and the Philosopher's Stone\",\n",
    "           \"26 June 1997\",\n",
    "           \"a wide adult audience as well as younger readers\",\n",
    "           \"eighty\"\n",
    "          ]\n",
    "\n",
    "for q,a in zip(queries,answers):\n",
    "      give_an_answer(context,q,a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# *Step 18:* Summarises"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I notice, in general that in questions that included words or phrases from the paragraph the model went perfectly.\n",
    "Sometimes when the question is more complicated or not so well-structured the model had very descent results.\n",
    "Given the fact that I train the model only with three epochs and I can't handle with overfitting, it has a very good performance.\n",
    "I compare the results with the already fined tuned model \"bert-large-uncased-whole-word-masking-finetuned-squad\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T12:55:11.312062Z",
     "iopub.status.busy": "2023-11-05T12:55:11.311431Z",
     "iopub.status.idle": "2023-11-05T12:55:13.631360Z",
     "shell.execute_reply": "2023-11-05T12:55:13.630297Z",
     "shell.execute_reply.started": "2023-11-05T12:55:11.312028Z"
    }
   },
   "outputs": [],
   "source": [
    "# Save model to Google Drive\n",
    "torch.save(model, '/kaggle/working/bert_finetunedmodel')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T13:02:39.363207Z",
     "iopub.status.busy": "2023-11-05T13:02:39.362807Z",
     "iopub.status.idle": "2023-11-05T13:02:39.369723Z",
     "shell.execute_reply": "2023-11-05T13:02:39.368818Z",
     "shell.execute_reply.started": "2023-11-05T13:02:39.363177Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import subprocess\n",
    "from IPython.display import FileLink, display\n",
    "\n",
    "def download_file(path, download_file_name):\n",
    "    os.chdir('/kaggle/working/')\n",
    "    zip_name = f\"/kaggle/working/{download_file_name}.zip\"\n",
    "    command = f\"zip {zip_name} {path} -r\"\n",
    "    result = subprocess.run(command, shell=True, capture_output=True, text=True)\n",
    "    if result.returncode != 0:\n",
    "        print(\"Unable to run zip command!\")\n",
    "        print(result.stderr)\n",
    "        return\n",
    "    display(FileLink(f'{download_file_name}.zip'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-05T13:03:28.966862Z",
     "iopub.status.busy": "2023-11-05T13:03:28.966428Z",
     "iopub.status.idle": "2023-11-05T13:04:40.540258Z",
     "shell.execute_reply": "2023-11-05T13:04:40.539339Z",
     "shell.execute_reply.started": "2023-11-05T13:03:28.966829Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<a href='bert_finetunedmodel.zip' target='_blank'>bert_finetunedmodel.zip</a><br>"
      ],
      "text/plain": [
       "/kaggle/working/bert_finetunedmodel.zip"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "download_file('/kaggle/working/bert_finetunedmodel', 'bert_finetunedmodel')\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
